<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/><meta name="exporter-version" content="Evernote Mac 9.1.3 (458534)"/><meta name="author" content="流星"/><meta name="created" content="2020-11-16 10:27:02 +0000"/><meta name="source" content="desktop.mac"/><meta name="updated" content="2020-12-20 14:28:43 +0000"/><meta name="content-class" content="yinxiang.markdown"/><title>TypeScript类型系统</title></head><body><div style="font-size: 14px; margin: 0; padding: 0; width: 100%;"><h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">@types</h2>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">使用 @types</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以通过 npm 来安装使用 @types，例如为 jquery 添加声明文件：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">npm install @types/jquery --save-dev
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">全局 @types</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">默认情况下，TypeScript 会自动包含支持全局使用的任何声明定义。例如，对于 jquery，你应该能够在项目中开始全局使用 $。</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">模块 @types</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">安装完之后，不需要特别的配置，你就可以像使用模块一样使用它：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">import * as $ from 'jquery';

// 现在你可以此模块中任意使用$了 :)
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">控制全局</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以通过配置 tsconfig.json 的 compilerOptions.types 选项，引入有意义的类型：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">{
  "compilerOptions": {
    "types" : [
      "jquery"
    ]
  }
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如上例所示，通过配置 compilerOptions.types: [ "jquery" ] 后，只允许使用 jquery 的 @types 包，即使这个人安装了另一个声明文件，比如 npm install @types/node，它的全局变量（例如 process）也不会泄漏到你的代码中，直到你将它们添加到 tsconfig.json 类型选项。</p>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">环境声明</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">环境声明允许你安全的使用现有的 JavaScript 库，并且能让你的 JavaScript、CoffeeScript 或者其他需要编译成 JavaScript 的语言逐步迁移至 TypeScript。<br/>
学习为第三方 JavaScript 库编写环境声明，是一种为 TypeScript 写注解比较好的实践方式。</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">声明文件</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">foo = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'foo' is not defined</span>


declare <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">var</span> foo: any;
foo = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// allow</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以选择把这些声明放入 .ts 或者 .d.ts 里。在你实际的项目里，我们强烈建议你应该把声明放入独立的 .d.ts 里（可以从一个命名为 global.d.ts 或者 vendor.d.ts 文件开始）。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如果一个文件有扩展名 .d.ts，这意味着每个根级别的声明都必须以 declare 关键字作为前缀。这有利于让开发者清楚的知道，在这里 TypeScript 将不会把它编译成任何代码，同时开发者需要确保这些在编译时存在。</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">变量</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当你想告诉 TypeScript 编辑器关于 process 变量时，你可以这么做：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">declare <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> process: any;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//这允许你使用 process，并能成功通过 TypeScript 的编译：</span>
process.exit();
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">我们推荐尽可能的使用接口，例如：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface Process {
  exit(code?: number): <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span>;
}

declare <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> process: Process;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//因为这允许其他人扩充这些全局变量，并且会告诉 TypeScript 有关于这些声明的修改。例如：考虑到以下情况，我们添加一个 exitWithLogging 函数至 process：</span>

interface Process {
  exitWithLogging(code?: number): <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span>;
}

process.exitWithLogging = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"/>) </span>{
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'exiting'</span>);
  process.exit.apply(process, <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">arguments</span>);
};
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">接口</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">下面两个是等效的声明, 示例 A 使用内联注解，示例 B 使用接口形式：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 示例 A</span>
declare <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> myPoint: { <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">x</span>: number; y: number };

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 示例 B</span>
interface Point {
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">x</span>: number;
  y: number;
}
declare <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> myPoint: Point;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">示例 B 的好处在于，如果有人创建了一个基于 myPoint 的库来添加新成员, 那么他可以轻松将此成员添加到 myPoint 的现有声明中:</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Lib a.d.ts</span>
interface Point {
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">x</span>: number,
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">y</span>: number
}
declare <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> myPoint: Point

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Lib b.d.ts</span>
interface Point {
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">z</span>: number
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Your code</span>
myPoint.z <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Allowed!</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">类可以实现接口</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如果你希望在类中使用必须要被遵循的接口（类）或别人定义的对象结构，可以使用 implements 关键字来确保其兼容性：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface Point {
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">x</span>: number;
  y: number;
  z: number; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// New member</span>
}

<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">MyPoint</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">implements</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Point</span> </span>{
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ERROR : missing member `z`</span>
  x: number;
  y: number;
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">注意</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><strong style="line-height: 160%; box-sizing: content-box; font-weight: 700;">并非每个接口都是很容易实现的</strong></p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface Crazy {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> (): {
    <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">hello</span>: number;
  };
}

<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">CrazyClass</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">implements</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Crazy</span> </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">constructor</span>() {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> { <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">hello</span>: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span> };
  }
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Because</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> crazy = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> CrazyClass(); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// crazy would be { hello:123 }</span>
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">枚举</h2>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">数字类型枚举</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">enum Color {
  Red,
  Green,
  Blue
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> col = Color.Red;
col = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 有效的，这也是 Color.Red</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 类型安全</span>
col = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'not a member of color'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: string 不能赋值给 `color` 类型</span>
</code></pre>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">enum Tristate {
  False,
  True,
  Unknown
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//编译后</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">var</span> Tristate;
(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Tristate</span>) </span>{
  Tristate[(Tristate[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'False'</span>] = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>)] = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'False'</span>;
  Tristate[(Tristate[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'True'</span>] = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>)] = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'True'</span>;
  Tristate[(Tristate[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Unknown'</span>] = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span>)] = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Unknown'</span>;
})(Tristate || (Tristate = {}));


<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(Tristate[<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>]); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 'False'</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(Tristate[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'False'</span>]); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 0</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(Tristate[Tristate.False]); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 'False' because `Tristate.False == 0`</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">先让我们聚焦 Tristate[Tristate['False'] = 0] = 'False' 这行代码，其中 Tristate['False'] = 0 的意思是将 Tristate 对象里的 False 成员值设置为 0。注意，JavaScript 赋值运算符返回的值是被赋予的值（在此例子中是 0），因此下一次 JavaScript 运行时执行的代码是 Tristate[0] = 'False'。</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">改变与数字枚举关联的数字</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//默认情况下，第一个枚举值是 0，然后每个后续值依次递增 1：</span>
enum Color {
  Red, <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 0</span>
  Green, <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 1</span>
  Blue <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 2</span>
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//但是，你可以通过特定的赋值来改变给任何枚举成员关联的数字</span>
enum Color {
  DarkRed = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">3</span>, <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 3</span>
  DarkGreen, <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 4</span>
  DarkBlue <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 5</span>
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">使用数字类型作为标志</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当你在使用这种标记的时候，这些位运算符 | (或)、&amp; （和）、~ （非）将会是你最好的朋友：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">enum AnimalFlags {
  None        = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>,
  HasClaws    = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span> &lt;&lt; <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>,
  CanFly      = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span> &lt;&lt; <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>
}

interface Animal {
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">flags</span>: AnimalFlags;
  [key: string]: any;
}

<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">printAnimalAbilities</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">animal: Animal</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">var</span> animalFlags = animal.flags;
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (animalFlags &amp; AnimalFlags.HasClaws) {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'animal has claws'</span>);
  }
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (animalFlags &amp; AnimalFlags.CanFly) {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'animal can fly'</span>);
  }
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (animalFlags == AnimalFlags.None) {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'nothing'</span>);
  }
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">var</span> animal = { <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">flags</span>: AnimalFlags.None };
printAnimalAbilities(animal); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// nothing</span>
animal.flags |= AnimalFlags.HasClaws;
printAnimalAbilities(animal); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// animal has claws</span>
animal.flags &amp;= ~AnimalFlags.HasClaws;
printAnimalAbilities(animal); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// nothing</span>
animal.flags |= AnimalFlags.HasClaws | AnimalFlags.CanFly;
printAnimalAbilities(animal); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// animal has claws, animal can fly</span>

</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">字符串枚举</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">export</span> enum EvidenceTypeEnum {
  UNKNOWN = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">''</span>,
  PASSPORT_VISA = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'passport_visa'</span>,
  PASSPORT = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'passport'</span>,
  SIGHTED_STUDENT_CARD = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'sighted_tertiary_edu_id'</span>,
  SIGHTED_KEYPASS_CARD = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'sighted_keypass_card'</span>,
  SIGHTED_PROOF_OF_AGE_CARD = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'sighted_proof_of_age_card'</span>
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//你可以使用它们用于简单的字符串比较：</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Where `someStringFromBackend` will be '' | 'passport_visa' | 'passport' ... etc.</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> value = someStringFromBackend <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">as</span> EvidenceTypeEnum;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Sample use in code</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (value === EvidenceTypeEnum.PASSPORT) {
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'You provided a passport'</span>);
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(value); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// `passport`</span>
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">常量枚举</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> enum Tristate {
  False,
  True,
  Unknown
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> lie = Tristate.False;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//编译后</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> lie = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">常量枚举 preserveConstEnums 选项</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">使用内联语法对性能有明显的提升作用。运行时没有 Tristate 变量的事实，是因为编译器帮助你把一些在运行时没有用到的不编译成 JavaScript。然而，你可能想让编译器仍然把枚举类型编译成 JavaScript，用于如上例子中从字符串到数字，或者是从数字到字符串的查找。在这种情景下，你可以使用编译选项 --preserveConstEnums，它会编译出 var Tristate 的定义，因此你在运行时，手动使用 Tristate['False'] 和 Tristate[0]。并且这不会以任何方式影响内联。</em></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">有静态方法的枚举</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以使用 enum + namespace 的声明的方式向枚举类型添加静态方法。如下例所示，我们将静态成员 isBusinessDay 添加到枚举上：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">enum Weekday {
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday,
  Sunday
}

namespace Weekday {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">export</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">isBusinessDay</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">day: Weekday</span>) </span>{
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">switch</span> (day) {
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> Weekday.Saturday:
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> Weekday.Sunday:
        <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">false</span>;
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">default</span>:
        <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">true</span>;
    }
  }
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> mon = Weekday.Monday;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> sun = Weekday.Sunday;

<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(Weekday.isBusinessDay(mon)); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// true</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(Weekday.isBusinessDay(sun));
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">开放式枚举</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">你只有在不使用模块时，开放式的枚举才有意义，你应该使用模块，因此这部分在文章最后。</em></p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//你可以跨多个文件拆分（和扩展）枚举定义，如下所示，你可以把 Color 的定义拆分至两个块中：</span>
enum Color {
  Red,
  Green,
  Blue
}

enum Color {
  DarkRed = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">3</span>,
  DarkGreen,
  DarkBlue
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">你应该在枚举的延续块中，初始化第一个成员，以便生成的代码不是先前定义的枚举类型值。TypeScript 将会发出警告，如果你定义初始值（错误信息：In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.）。</em></p>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">lib.d.ts</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当你安装 TypeScript 时，会顺带安装一个 lib.d.ts 声明文件。这个文件包含 JavaScript 运行时以及 DOM 中存在各种常见的环境声明。<br/>
1.它自动包含在 TypeScript 项目的编译上下文中；<br/>
2.它能让你快速开始书写经过类型检查的 JavaScript 代码。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">你可以通过指定 --noLib 的编译器命令行标志（或者在 tsconfig.json 中指定选项 noLib: true）从上下文中排除此文件。</em></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">使用例子</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> bar = foo.toString();<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//这段代码的类型检查正常，因为 lib.d.ts 为所有 JavaScript 对象定义了 toString 方法</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//在 noLib 选项下</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> bar = foo.toString(); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 属性 toString 不存在类型 number 上</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">观察 lib.d.ts 的内容</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">lib.d.ts 的内容主要是一些变量声明（如：window、document、math）和一些类似的接口声明（如：Window、Document、Math）。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">让我们来看一个变量声明的示例，如 window 被定义为：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">declare <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">var</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">window</span>: Window;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">这只是一个简单的 declare var，后面跟一个变量名称（window）和一个用来类型注解的接口（Window），这些变量通常指向一些全局的接口，例如，以下是 Window 接口的一小部分：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface Window
  extends EventTarget,
    WindowTimers,
    WindowSessionStorage,
    WindowLocalStorage,
    WindowConsole,
    GlobalEventHandlers,
    IDBEnvironment,
    WindowBase64 {
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">animationStartTime</span>: number;
  applicationCache: ApplicationCache;
  clientInformation: Navigator;
  closed: boolean;
  crypto: Crypto;
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// so on and so forth...</span>
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">修改原始类型</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在 TypeScript 中，接口是开放式的，这意味着当你想使用不存在的成员时，只需要将它们添加至 lib.d.ts 中的接口声明中即可，TypeScript 将会自动接收它。注意，你需要在全局模块中做这些修改，以使这些接口与 lib.d.ts 相关联。我们推荐你创建一个称为 global.d.ts 的特殊文件。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">这里有我们需要添加至 Window，Math，Date 的一些例子：</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">Window：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface Window {
  helloWorld(): <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">void</span>;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Add it at runtime</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">window</span>.helloWorld = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">()</span> =&gt;</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello world'</span>);

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Call it</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">window</span>.helloWorld();

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 滥用会导致错误</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">window</span>.helloWorld(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'gracius'</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 提供的参数与目标不匹配</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">使用你自己定义的 lib.d.ts</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">正如上文所说，使用 --noLib 编译选项会导致 TypeScript 排除自动包含的 lib.d.ts 文件。为什么这个功能是有效的，我例举了一些常见原因：</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">1.运行的 JavaScript 环境与基于标准浏览器运行时环境有很大不同；<br/>
2.你希望在代码里严格的控制全局变量，例如：lib.d.ts 将 item 定义为全局变量，你不希望它泄漏到你的代码里</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">一旦你排除了默认的 lib.d.ts 文件，你就可以在编译上下文中包含一个命名相似的文件，TypeScript 将提取该文件进行类型检查。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">小心使用 --noLib 选项，一旦你使用了它，当你把你的项目分享给其他人时，它们也将被迫使用 --noLib 选项，更糟糕的是，如果将这些代码放入你的项目中，你可能需要将它们移植到基于你的代码的 lib 中。</em></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">编译目标对 lib.d.ts 的影响</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">设置编译目标为 es6 时，能导致 lib.d.ts 包含更多像 Promise 现代（es6）内容的环境声明。编译器目标的这种作用，改变了代码的环境，这对某些人来说是理想的，但是这对另外一些人来说造成了困扰，因为它将编译出的代码与环境混为一谈。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当你想对环境进行更细粒的控制时，你应该使用我们接下来将要讨论的 --lib 选项。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">有时，你想要解耦编译目标（即生成的 JavaScript 版本）和环境库支持之间的关系。例如对于 Promise，你的编译目标是 --target es5，但是你仍然想使用它，这时，你可以使用 lib 对它进行控制。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以通过命令行或者在 tsconfig.json 中提供此选项（推荐）：</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">命令行:</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">tsc --target es5 --lib dom,es6
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">config.json</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">"compilerOptions": {
    "lib": ["dom", "es6"]
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">lib 分类如下：</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">JavaScript 功能<br/>
es5<br/>
es6<br/>
es2015<br/>
es7<br/>
es2016<br/>
es2017<br/>
esnext<br/>
运行环境<br/>
dom<br/>
dom.iterable<br/>
webworker<br/>
scripthost<br/>
ESNext 功能选项<br/>
es2015.core<br/>
es2015.collection<br/>
es2015.generator<br/>
es2015.iterable<br/>
es2015.promise<br/>
es2015.proxy<br/>
es2015.reflect<br/>
es2015.symbol<br/>
es2015.symbol.wellknown<br/>
es2016.array.include<br/>
es2017.object<br/>
es2017.sharedmemory<br/>
esnext.asynciterable</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">*--lib 选项提供非常精细的控制，因此你最有可能从运行环境与 JavaScript 功能类别中分别选择一项，如果你没有指定 --lib，则会导入默认库：</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">--target 选项为 es5 时，会导入 es5, dom, scripthost。<br/>
--target 选项为 es6 时，会导入 es6, dom, dom.iterable, scripthost。</em>*</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">在旧的 JavaScript 引擎时使用 Polyfill</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">要使用一些新功能如 Map、Set、Promise（随着时间推移会变化），你可以使用现代的 lib 选项，并且需要安装 core-js：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">npm install core-js --save-dev
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">接着，在你的项目里导入它：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">import 'core-js';
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">函数</h2>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">参数注解</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// variable annotation</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> sampleVariable: { <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">bar</span>: number };

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// function parameter annotation</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">sampleParameter: { bar: number }</span>) </span>{}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">返回类型注解</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface Foo {
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">foo</span>: string;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Return type annotated as `: Foo`</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">sample: Foo</span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Foo</span> </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> sample;
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">可选参数</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以将参数标记为可选:</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">bar: number, bas?: string</span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">void</span> </span>{
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ..</span>
}

foo(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>);
foo(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>, <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span>);
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">或者，当调用者没有提供该参数时，你可以提供一个默认值（在参数声明后使用 = someValue ）：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">bar: number, bas: string = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span></span>) </span>{
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(bar, bas);
}

foo(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 123, hello</span>
foo(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>, <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'world'</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 123, world</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">重载</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 重载</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">padding</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">all: number</span>);
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">padding</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">topAndBottom: number, leftAndRight: number</span>);
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">padding</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">top: number, right: number, bottom: number, left: number</span>);
// <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Actual</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">implementation</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">that</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">is</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">a</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">true</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">representation</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">of</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">all</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">the</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">cases</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">the</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">body</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">needs</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">to</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">handle</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">padding</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">a: number, b?: number, c?: number, d?: number</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (b === <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">undefined</span> &amp;&amp; c === <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">undefined</span> &amp;&amp; d === <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">undefined</span>) {
    b = c = d = a;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (c === <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">undefined</span> &amp;&amp; d === <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">undefined</span>) {
    c = a;
    d = b;
  }
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> {
    <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">top</span>: a,
    <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">right</span>: b,
    <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">bottom</span>: c,
    <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">left</span>: d
  };
}


padding(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Okay: all</span>
padding(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Okay: topAndBottom, leftAndRight</span>
padding(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Okay: top, right, bottom, left</span>

padding(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: Not a part of the available overloads</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">函数声明</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在没有提供函数实现的情况下，有两种声明函数类型的方式:</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">type LongHand = {
  (a: number): number;
};

type ShortHand = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">a: number</span>) =&gt;</span> number;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">但是，当你想使用函数重载时，只能用第一种方式:</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">type LongHandAllowsOverloadDeclarations = {
  (a: number): number;
  (a: string): string;
};
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">可调用的</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以使用类型别名或者接口来表示一个可被调用的类型注解：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface ReturnString {
  (): string;
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">它可以表示一个返回值为 string 的函数：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">declare <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo: ReturnString;

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> bar = foo(); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// bar 被推断为一个字符串。</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">一个实际的例子</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当然，像这样一个可被调用的类型注解，你也可以根据实际来传递任何参数、可选参数以及 rest 参数，这有一个稍微复杂的例子：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface Complex {
  (foo: string, bar?: number, ...others: boolean[]): number;
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">一个接口可提供多种调用签名，用以特殊的函数重载：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface Overloaded {
  (foo: string): string;
  (foo: number): number;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 实现接口的一个例子：</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">stringOrNumber</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo: number</span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">number</span>;
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">stringOrNumber</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo: string</span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">string</span>;
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">stringOrNumber</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo: any</span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">any</span> </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> foo === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'number'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> foo * foo;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> foo === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'string'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">`hello <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">${foo}</span>`</span>;
  }
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> overloaded: Overloaded = stringOrNumber;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 使用</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> str = overloaded(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">''</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// str 被推断为 'string'</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> num = overloaded(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// num 被推断为 'number'</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">这也可以用于内联注解中：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> overloaded: {
  (foo: string): string;
  (foo: number): number;
};
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">箭头函数</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">为了使指定可调用的类型签名更容易，TypeScript 也允许你使用简单的箭头函数类型注解。例如，在一个以 number 类型为参数，以 string 类型为返回值的函数中，你可以这么写：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> simple: <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo: number</span>) =&gt;</span> string = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span> =&gt;</span> foo.toString();
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">它仅仅只能作为简单的箭头函数，你无法使用重载。如果想使用重载，你必须使用完整的 { (someArgs): someReturn } 的语法</em></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">可实例化</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">可实例化仅仅是可调用的一种特殊情况，它使用 new 作为前缀。它意味着你需要使用 new 关键字去调用它：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">interface CallMeWithNewToGetString {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> (): string;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 使用</span>
declare <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> Foo: CallMeWithNewToGetString;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> bar = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Foo(); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// bar 被推断为 string 类型</span>
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">类型断言</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">TypeScript 允许你覆盖它的推断，并且能以你任何你想要的方式分析它，这种机制被称为「类型断言」。TypeScript 类型断言用来告诉编译器你比它更了解这个类型，并且它不应该再发出错误。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">类型断言的一个常见用例是当你从 JavaScript 迁移到 TypeScript 时：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = {};
foo.bar = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'bar' 属性不存在于 ‘{}’</span>
foo.bas = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'bas' 属性不存在于 '{}'</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">这里的代码发出了错误警告，因为 foo 的类型推断为 {}，即是具有零属性的对象。因此，你不能在它的属性上添加 bar 或 bas，你可以通过类型断言来避免此问题：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Foo {
  bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  bas: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = {} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">as</span> Foo;
foo.bar = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>;
foo.bas = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span>;
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">as foo 与 &lt;foo&gt;</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">最初的断言语法如下所示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar = &lt;<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>&gt;foo; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 现在 bar 的类型是 'string'</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">然而，当你在 JSX 中使用 &lt;foo&gt; 的断言语法时，这会与 JSX 的语法存在歧义：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">let foo = &lt;string&gt;bar;&lt;/string&gt;;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">因此，为了一致性，我们建议你使用 as foo 的语法来为类型断言。</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">类型断言与类型转换</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">它之所以不被称为「类型转换」，是因为转换通常意味着某种运行时的支持。但是，类型断言纯粹是一个编译时语法，同时，它也是一种为编译器提供关于如何分析代码的方法。</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">类型断言被认为是有害的</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在很多情景下，断言能让你更容易的从遗留项目中迁移（甚至将其他代码粘贴复制到你的项目中），然而，你应该小心谨慎的使用断言。让我们用最初的代码作为示例，如果你没有按约定添加属性，TypeScript 编译器并不会对此发出错误警告：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Foo {
  bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  bas: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = {} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">as</span> Foo;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ahhh, 忘记了什么？</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">另外一个常见的想法是使用类型断言来提供代码的提示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Foo {
  bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  bas: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = &lt;Foo&gt;{
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 编译器将会提供关于 Foo 属性的代码提示</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 但是开发人员也很容易忘记添加所有的属性</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 同样，如果 Foo 被重构，这段代码也可能被破坏（例如，一个新的属性被添加）。</span>
};
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">这也会存在一个同样的问题，如果你忘记了某个属性，编译器同样也不会发出错误警告。使用一种更好的方式：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Foo {
  bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  bas: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo: Foo = {
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 编译器将会提供 Foo 属性的代码提示</span>
};
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在某些情景下，你可能需要创建一个临时的变量，但至少，你不会使用一个承诺（可能是假的），而是依靠类型推断来检查你的代码。</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">双重断言</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">类型断言，尽管我们已经证明了它并不是那么安全，但它也还是有用武之地。如下一个非常实用的例子所示，当使用者了解传入参数更具体的类型时，类型断言能按预期工作：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">handler</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">event: Event</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> mouseEvent = event <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">as</span> MouseEvent;
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">然而，如下例子中的代码将会报错，尽管使用者已经使用了类型断言：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">handler</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">event: Event</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> element = event <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">as</span> HTMLElement; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'Event' 和 'HTMLElement' 中的任何一个都不能赋值给另外一个</span>
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如果你仍然想使用那个类型，你可以使用双重断言。首先断言成兼容所有类型的 any，编译器将不会报错：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">handler</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">event: Event</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> element = (event <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">as</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span>) <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">as</span> HTMLElement; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">TypeScript 是怎么确定单个断言是否足够</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当 S 类型是 T 类型的子集，或者 T 类型是 S 类型的子集时，S 能被成功断言成 T。这是为了在进行类型断言时提供额外的安全性，完全毫无根据的断言是危险的，如果你想这么做，你可以使用 any。</p>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">Freshness</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">为了能让检查对象字面量类型更容易，TypeScript 提供 「Freshness」 的概念（它也被称为更严格的对象字面量检查）用来确保对象字面量在结构上类型兼容。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">结构类型非常方便。考虑如下例子代码，它可以让你非常便利的从 JavaScript 迁移至 TypeScript，并且会提供类型安全：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">logName</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">something: { name: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> }</span>) </span>{
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(something.name);
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> person = { name: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'matt'</span>, job: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'being awesome'</span> };
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> animal = { name: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'cow'</span>, diet: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'vegan, but has milk of own specie'</span> };
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> randow = { note: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">`I don't have a name property`</span> };

logName(person); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
logName(animal); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
logName(randow); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 没有 `name` 属性</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">但是，结构类型有一个缺点，它能误导你认为某些东西接收的数据比它实际的多。如下例，TypeScript 发出错误警告：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">logName</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">something: { name: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> }</span>) </span>{
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(something.name);
}

logName({ name: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'matt'</span> }); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
logName({ name: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'matt'</span>, job: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'being awesome'</span> }); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 对象字面量只能指定已知属性，`job` 属性在这里并不存在。</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">请注意，这种错误提示，只会发生在对象字面量上。</em></p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">另外一个使用比较多的场景是与具有可选成员的接口一起使用，如果没有这样的对象字面量检查，当你输入错误单词的时候，并不会发出错误警告：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">logIfHasName</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">something: { name?: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> }</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (something.name) {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(something.name);
  }
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> person = { name: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'matt'</span>, job: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'being awesome'</span> };
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> animal = { name: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'cow'</span>, diet: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'vegan, but has milk of own species'</span> };

logIfHasName(person); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// okay</span>
logIfHasName(animal); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// okay</span>

logIfHasName({ neme: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'I just misspelled name to neme'</span> }); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 对象字面量只能指定已知属性，`neme` 属性不存在。</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">允许额外的属性</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">一个类型能够包含索引签名，以明确表明可以使用额外的属性:</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> x: { foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, [x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>]: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span> };

x = { foo: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, baz: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span> }; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok, 'baz' 属性匹配于索引签名</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">用例：React State</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">Facebook ReactJS 为对象的 Freshness 提供了一个很好的用例，通常在组件中，你只使用少量属性，而不是传入所有，来调用 setState：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 假设</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> State {
  foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
  bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 你可能想做：</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.setState({ foo: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span> }); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 没有属性 'bar'</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 因为 state 包含 'foo' 与 'bar'，TypeScript 会强制你这么做：</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.setState({ foo: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span>, bar: <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.state.bar });

</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如果你想使用 Freshness，你可能需要将所有成员标记为可选，这仍然会捕捉到拼写错误：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 假设</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> State {
  foo?: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
  bar?: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 你可能想做</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.setState({ foo: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span> }); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Yay works fine!</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 由于 Freshness，你也可以防止错别字</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.setState({ foos: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span> }}; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 对象只能指定已知属性</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 仍然会有类型检查</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.setState({ foo: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span> }}; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 无法将 number 类型赋值给 string 类型</span>
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">类型保护</h2>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">typeof和instanceof</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">TypeScript 熟知 JavaScript 中 instanceof 和 typeof 运算符的用法。如果你在一个条件块中使用这些，TypeScript 将会推导出在条件块中的的变量类型</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">doSome</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span> | <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span></span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> x === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'string'</span>) {
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 在这个块中，TypeScript 知道 `x` 的类型必须是 `string`</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(x.subtr(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>)); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'subtr' 方法并没有存在于 `string` 上</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(x.substr(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>)); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
  }

  x.substr(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 无法保证 `x` 是 `string` 类型</span>
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//这有一个关于 class 和 instanceof 的例子：</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Foo {
  foo = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>;
  common = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'123'</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Bar {
  bar = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>;
  common = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'123'</span>;
}

<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">doStuff</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">arg: Foo | Bar</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (arg <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">instanceof</span> Foo) {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.foo); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.bar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
  }
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (arg <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">instanceof</span> Bar) {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.foo); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.bar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
  }
}

doStuff(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Foo());
doStuff(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Bar());

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//TypeScript 甚至能够理解 else。当你使用 if 来缩小类型时，TypeScript 知道在其他块中的类型并不是 if 中的类型：</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Foo {
  foo = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Bar {
  bar = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>;
}

<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">doStuff</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">arg: Foo | Bar</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (arg <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">instanceof</span> Foo) {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.foo); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.bar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 这个块中，一定是 'Bar'</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.foo); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.bar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
  }
}

doStuff(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Foo());
doStuff(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Bar());
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">in</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">in 操作符可以安全的检查一个对象上是否存在一个属性，它通常也被作为类型保护使用：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> A {
  x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> B {
  y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
}

<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">doStuff</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">q: A | B</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'x'</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">in</span> q) {
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// q: A</span>
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// q: B</span>
  }
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">字面量类型保护</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当你在联合类型里使用字面量类型时，你可以检查它们是否有区别：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Foo = {
  kind: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'foo'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 字面量类型</span>
  foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
};

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Bar = {
  kind: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'bar'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 字面量类型</span>
  bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
};

<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">doStuff</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">arg: Foo | Bar</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (arg.kind === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'foo'</span>) {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.foo); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.bar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 一定是 Bar</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.foo); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.bar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
  }
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">使用定义的类型保护</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">JavaScript 并没有内置非常丰富的、运行时的自我检查机制。当你在使用普通的 JavaScript 对象时（使用结构类型，更有益处），你甚至无法访问 instanceof 和 typeof。在这种情景下，你可以创建用户自定义的类型保护函数，这仅仅是一个返回值为类似于someArgumentName is SomeType 的函数，如下：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 仅仅是一个 interface</span>
interface Foo {
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">foo</span>: number;
  common: string;
}

interface Bar {
  <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">bar</span>: number;
  common: string;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 用户自己定义的类型保护！</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">isFoo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">arg: Foo | Bar</span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">arg</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">is</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Foo</span> </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> (arg <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">as</span> Foo).foo !== <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">undefined</span>;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 用户自己定义的类型保护使用用例：</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">doStuff</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">arg: Foo | Bar</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (isFoo(arg)) {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.foo); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.bar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.foo); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(arg.bar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
  }
}

doStuff({ <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">foo</span>: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>, <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">common</span>: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'123'</span> });
doStuff({ <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">bar</span>: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>, <span style="color: #9cdcfe; line-height: 160%; box-sizing: content-box;">common</span>: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'123'</span> });
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">字面量类型</h2>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">字符串字面量</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在这里，我们创建了一个被称为 foo 变量，它仅接收一个字面量值为 Hello 的变量：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span>;
foo = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Bar'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'bar' 不能赋值给类型 'Hello'</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">它们本身并不是很实用，但是可以在一个联合类型中组合创建一个强大的（实用的）抽象：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> CardinalDirection = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'North'</span> | <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'East'</span> | <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'South'</span> | <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'West'</span>;

<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">move</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">distance: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, direction: CardinalDirection</span>) </span>{
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ...</span>
}

move(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'North'</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
move(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Nurth'</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">其他字面量类型</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">TypeScript 同样也提供 boolean 和 number 的字面量类型：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> OneToFive = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span> | <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span> | <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">3</span> | <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">4</span> | <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">5</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Bools = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">true</span> | <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">false</span>;
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">推断</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">iTakeFoo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo: 'foo'</span>) </span>{}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> test = {
  someProp: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'foo'</span>
};

iTakeFoo(test.someProp); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: Argument of type string is not assignable to parameter of type 'foo'</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">这是由于 test 被推断为 { someProp: string }，我们可以采用一个简单的类型断言来告诉 TypeScript 你想推断的字面量：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">iTakeFoo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo: 'foo'</span>) </span>{}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> test = {
  someProp: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'foo'</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">as</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'foo'</span>
};

iTakeFoo(test.someProp); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">或者使用类型注解的方式，来帮助 TypeScript 推断正确的类型：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">iTakeFoo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo: 'foo'</span>) </span>{}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Test = {
  someProp: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'foo'</span>;
};

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> test: Test = {
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 推断 `someProp` 永远是 'foo'</span>
  someProp: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'foo'</span>
};

iTakeFoo(test.someProp); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">使用用例</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 用于创建字符串列表映射至 `K: V` 的函数</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">strEnum</span>&lt;<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">T</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">extends</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">string</span>&gt;(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">o: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Array</span>&lt;T&gt;</span>): </span>{ [K <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">in</span> T]: K } {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> o.reduce(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">res, key</span>) =&gt;</span> {
    res[key] = key;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> res;
  }, <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Object</span>.create(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">null</span>));
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 创建 K: V</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> Direction = strEnum([<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'North'</span>, <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'South'</span>, <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'East'</span>, <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'West'</span>]);

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//使用 keyof、typeof 来生成字符串的联合类型</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Direction = keyof <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> Direction;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 简单的使用</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> sample: Direction;

sample = Direction.North; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Okay</span>
sample = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'North'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Okay</span>
sample = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'AnythingElse'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ERROR!</span>
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">readonly</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">TypeScript 类型系统允许你在一个接口里使用 readonly 来标记属性。它能让你以一种更安全的方式工作（不可预期的改变是很糟糕的）：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">config: { readonly bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, readonly bas: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span> }</span>) </span>{
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ..</span>
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> config = { bar: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>, bas: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span> };
foo(config);

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 现在你能够确保 'config' 不能够被改变了</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当然，你也可以在 interface 和 type 里使用 readonly：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Foo = {
  readonly bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  readonly bas: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
};

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 初始化</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo: Foo = { bar: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>, bas: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">456</span> };

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 不能被改变</span>
foo.bar = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">456</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: foo.bar 为仅读属性</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你也能指定一个类的属性为只读，然后在声明时或者构造函数中初始化它们，如下所示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Foo {
  readonly bar = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// OK</span>
  readonly baz: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">constructor</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"/>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.baz = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// OK</span>
  }
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">绝对的不可变</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你甚至可以把索引签名标记为只读：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Foo {
  readonly [x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>]: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 使用</span>

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo: Foo = { <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span>: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">345</span> };
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(foo[<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>]); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok（读取）</span>
foo[<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>] = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">456</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 属性只读</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如果你想以不变的方式使用原生 JavaScript 数组，可以使用 TypeScript 提供的 ReadonlyArray&lt;T&gt; 接口：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: ReadonlyArray&lt;<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>&gt; = [<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">3</span>];
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(foo[<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>]); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
foo.push(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">4</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: ReadonlyArray 上不存在 `push`，因为他会改变数组</span>
foo = foo.concat(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">4</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok, 创建了一个复制</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">自动推断</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在一些情况下，编译器能把一些特定的属性推断为 readonly，例如在一个 class 中，如果你有一个只含有 getter 但是没有 setter 的属性，他能被推断为只读：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Person {
  firstName: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'John'</span>;
  lastName: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Doe'</span>;

  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">get</span> fullName() {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.firstName + <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.lastName;
  }
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> person = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Person();

<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(person.fullName); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// John Doe</span>
person.fullName = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Dear Reader'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error, fullName 只读</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">与 const 的不同</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">const<br/>
1.用于变量；<br/>
2.变量不能重新赋值给其他任何事物。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">readonly<br/>
1.用于属性；<br/>
2.用于别名，可以修改属性；</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo: {
  readonly bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
} = {
  bar: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>
};

<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">iMutateFoo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo: { bar: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span> }</span>) </span>{
  foo.bar = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">456</span>;
}

iMutateFoo(foo);
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(foo.bar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 456</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">readonly 能确保“我”不能修改属性，但是当你把这个属性交给其他并没有这种保证的使用者（允许出于类型兼容性的原因），他们能改变它。</em></p>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">泛型</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">泛型的关键目的是在成员之间提供有意义的约束</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">下面是对一个先进先出的数据结构——队列，在 TypeScript 和 JavaScript 中的简单实现。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Queue {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">private</span> data = [];
  push = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">item</span> =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.data.push(item);
  pop = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">()</span> =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.data.shift();
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在上述代码中存在一个问题，它允许你向队列中添加任何类型的数据，当然，当数据被弹出队列时，也可以是任意类型。在下面的示例中，看起来人们可以向队列中添加string 类型的数据，但是实际上，该用法假定的是只有 number 类型会被添加到队列里。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Queue {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">private</span> data = [];
  push = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">item</span> =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.data.push(item);
  pop = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">()</span> =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.data.shift();
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> queue = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Queue();

queue.push(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>);
queue.push(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'1'</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Oops，一个错误</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 一个使用者，走入了误区</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(queue.pop().toPrecision(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>));
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(queue.pop().toPrecision(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>)); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// RUNTIME ERROR</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">一个解决的办法（事实上，这也是不支持泛型类型的唯一解决办法）是为这些约束创建特殊类，如快速创建数字类型的队列：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> QueueNumber {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">private</span> data = [];
  push = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">item: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.data.push(item);
  pop = (): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">number</span> =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.data.shift();
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> queue = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> QueueNumber();

queue.push(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>);
queue.push(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'1'</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 不能推入一个 `string` 类型，只能是 `number` 类型</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如果该错误得到修复，其他将不会出现问题</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当然，快速也意味着痛苦。例如当你想创建一个字符串的队列时，你将不得不再次修改相当大的代码。我们真正想要的一种方式是无论什么类型被推入队列，被推出的类型都与推入类型一样。当你使用泛型时，这会很容易：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 创建一个泛型类</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Queue&lt;T&gt; {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">private</span> data: T[] = [];
  push = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">item: T</span>) =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.data.push(item);
  pop = (): T | <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">undefined</span> =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.data.shift();
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 简单的使用</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> queue = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Queue&lt;<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>&gt;();
queue.push(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>);
queue.push(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'1'</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error：不能推入一个 `string`，只有 number 类型被允许</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">误用的泛型</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">我见过开发者使用泛型仅仅是为了它的 hack。当你使用它时，你应该问问自己：你想用它来提供什么样的约束。如果你不能很好的回答它，你可能会误用泛型，如：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">declare</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span>&lt;<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">T</span>&gt;(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">arg: T</span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">void</span></span>;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在这里，泛型完全没有必要使用，因为它仅用于单个参数的位置，使用如下方式可能更好：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">declare</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">arg: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span></span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">void</span></span>;
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">配合 axios 使用</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">通常情况下，我们会把后端返回数据格式单独放入一个 interface 里：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 请求接口数据</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">export</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> ResponseData&lt;T = any&gt; {
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**
   * 状态码
   * @type { number }
   */</span>
  code: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;

  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**
   * 数据
   * @type { T }
   */</span>
  result: T;

  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/**
   * 消息
   * @type { string }
   */</span>
  message: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当我们把 API 单独抽离成单个模块时：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 在 axios.ts 文件中对 axios 进行了处理，例如添加通用配置、拦截器等</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">import</span> Ax <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">from</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'./axios'</span>;

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">import</span> { ResponseData } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">from</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'./interface.ts'</span>;

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">export</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">getUser</span>&lt;<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">T</span>&gt;(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"/>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> Ax.get&lt;ResponseData&lt;T&gt;&gt;(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'/somepath'</span>)
    .then(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">res</span> =&gt;</span> res.data)
    .catch(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">err</span> =&gt;</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.error(err));
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">接着我们写入返回的数据类型 User，这可以让 TypeScript 顺利推断出我们想要的类型：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> User {
  name: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
  age: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">async</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">test</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"/>) </span>{
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// user 被推断出为</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// {</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//  code: number,</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//  result: { name: string, age: number },</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//  message: string</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// }</span>
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> user = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">await</span> getUser&lt;User&gt;();
}
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">类型推断</h2>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">定义变量</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// foo 是 'number'</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// bar 是 'string'</span>

foo = bar; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 不能将 'string' 赋值给 `number`</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">函数返回类型</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">add</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">a: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, b: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> a + b;
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">赋值</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Adder = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">a: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, b: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) =&gt;</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: Adder = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">a, b</span>) =&gt;</span> a + b;
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">结构化</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = {
  a: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>,
  b: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">456</span>
};

foo.a = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error：不能把 'string' 类型赋值给 'number' 类型</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">解构</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = {
  a: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>,
  b: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">456</span>
};
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> { a } = foo;

a = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error：不能把 'string' 类型赋值给 'number' 类型</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">警告</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//例子1：小心使用参数</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">a, b</span>) =&gt;</span> {
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/* do something */</span>
};


<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//例子2：小心使用返回值</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">a: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, b: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> a + addOne(b);
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 一些使用 JavaScript 库的特殊函数</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">addOne</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">a</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> a + <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>;
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">noImplicitAny</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">选项 noImplicitAny 用来告诉编译器，当无法推断一个变量时发出一个错误（或者只能推断为一个隐式的 any 类型），你可以：<br/>
1、通过显式添加 :any 的类型注解，来让它成为一个 any 类型；<br/>
2、通过一些更正确的类型注解来帮助 TypeScript 推断类型。</p>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">类型兼容性</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">类型兼容性用于确定一个类型是否能赋值给其他类型。<br/>
如 string 类型与 number 类型不兼容：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> str: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> num: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span> = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>;

str = num; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'number' 不能赋值给 'string'</span>
num = str; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'string' 不能赋值给 'number'</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">安全性</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">TypeScript 类型系统设计比较方便，它允许你有一些不正确的行为。例如：任何类型都能被赋值给 any，这意味着告诉编译器你可以做任何你想做的事情：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">let foo: any = 123;
foo = 'hello';

foo.toPrecision(3);
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">结构化</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">TypeScript 对象是一种结构类型，这意味着只要结构匹配，名称也就无关紧要了：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Point {
  x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Point2D {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">constructor</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) {}
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> p: Point;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok, 因为是结构化的类型</span>
p = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Point2D(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span>);
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">变体</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">对一个简单类型 Base 和 Child 来说，如果 Child 是 Base 的子类，Child 的实例能被赋值给 Base 类型的变量。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在由 Base 和 Child 组合的复杂类型的类型兼容性中，它取决于相同场景下的 Base 与 Child 的变体：</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">协变（Covariant）：只在同一个方向；</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">逆变（Contravariant）：只在相反的方向；</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">双向协变（Bivariant）：包括同一个方向和不同方向；</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">不变（Invariant）：如果类型不完全相同，则它们是不兼容的。</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">对于存在完全可变数据的健全的类型系统（如 JavaScript），Invariant 是一个唯一的有效可选属性，但是如我们说讨论的，便利性迫使我们作出一些不是很安全的选择。</em></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">函数</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当你在比较两个函数时，这有一些你需要考虑到的事情</p>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">返回类型</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">协变（Covariant）：返回类型必须包含足够的数据。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Point2D {
  x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Point3D {
  x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  z: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> iMakePoint2D = (): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Point2D</span> =&gt;</span> ({ x: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>, y: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> });
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> iMakePoint3D = (): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Point3D</span> =&gt;</span> ({ x: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>, y: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>, z: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> });

iMakePoint2D = iMakePoint3D;
iMakePoint3D = iMakePoint2D; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ERROR: Point2D 不能赋值给 Point3D</span>
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">参数数量</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">更少的参数数量是好的（如：函数能够选择性的忽略一些多余的参数），但是你得保证有足够的参数被使用了：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> iTakeSomethingAndPassItAnErr = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">x: (<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">err: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Error</span>, data: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span></span>) =&gt; <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">void</span></span>) =&gt;</span> {
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/* 做一些其他的 */</span>
};

iTakeSomethingAndPassItAnErr(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">()</span> =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">null</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
iTakeSomethingAndPassItAnErr(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">err</span> =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">null</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
iTakeSomethingAndPassItAnErr(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">err, data</span>) =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">null</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 参数类型 `(err: any, data: any, more: any) =&gt; null` 不能赋值给参数类型 `(err: Error, data: any) =&gt; void`</span>
iTakeSomethingAndPassItAnErr(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">err, data, more</span>) =&gt;</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">null</span>);
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">可选的和 rest 参数</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">可选的（预先确定的）和 Rest 参数（任何数量的参数）都是兼容的：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) =&gt;</span> {};
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">x?: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, y?: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) =&gt;</span> {};
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bas = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">...args: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>[]</span>) =&gt;</span> {};

foo = bar = bas;
bas = bar = foo;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//可选的（上例子中的 bar）与不可选的（上例子中的 foo）仅在选项为 strictNullChecks 为 false 时兼容。</span>
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">函数参数类型</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">双向协变（Bivariant）：旨在支持常见的事件处理方案。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Point2D {
  x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Point3D {
  x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  z: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> iTakePoint2D = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">point: Point2D</span>) =&gt;</span> {};
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> iTakePoint3D = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">point: Point3D</span>) =&gt;</span> {};

iTakePoint3D = iTakePoint2D; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok, 这是合理的</span>
iTakePoint2D = iTakePoint3D; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok，为什么？</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">枚举</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">枚举与数字类型相互兼容</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">enum</span> Status {
  Ready,
  Waiting
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> status = Status.Ready;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> num = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>;

status = num;
num = status;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">来自于不同枚举的枚举变量，被认为是不兼容的：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">enum</span> Status {
  Ready,
  Waiting
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">enum</span> Color {
  Red,
  Blue,
  Green
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> status = Status.Ready;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> color = Color.Red;

status = color; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">类</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">仅仅只有实例成员和方法会相比较，构造函数和静态成员不会被检查。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Animal {
  feet: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">constructor</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">name: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>, numFeet: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) {}
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Size {
  feet: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">constructor</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">meters: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) {}
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> a: Animal;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> s: Size;

a = s; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// OK</span>
s = a; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// OK</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">私有的和受保护的成员必须来自于相同的类。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Animal {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">protected</span> feet: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Cat <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">extends</span> Animal {}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> animal: Animal;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> cat: Cat;

animal = cat; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
cat = animal; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Size {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">protected</span> feet: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> size: Size;

animal = size; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ERROR</span>
size = animal; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ERROR</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">泛型</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">TypeScript 类型系统基于变量的结构，仅当类型参数在被一个成员使用时，才会影响兼容性。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">//当 T 没有被成员使用时，它对兼容性没有影响：
interface Empty&lt;T&gt; {}

let x: Empty&lt;number&gt;;
let y: Empty&lt;string&gt;;

x = y; // ok

//当 T 被成员使用时，它将在实例化泛型后影响兼容性：
//如果尚未实例化泛型参数，则在检查兼容性之前将其替换为 any：
interface Empty&lt;T&gt; {
  data: T;
}

let x: Empty&lt;number&gt;;
let y: Empty&lt;string&gt;;

x = y; // Error
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">脚注：不变性（Invariance）</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">我们说过，不变性可能是唯一一个听起来合理的选项，这里有一个关于 contra 和 co 的变体，被认为对数组是不安全的。
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Animal {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">constructor</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> name: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span></span>) {}
}
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Cat <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">extends</span> Animal {
  meow() {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'cat'</span>);
  }
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> animal = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Animal(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'animal'</span>);
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> cat = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Cat(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'cat'</span>);

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 多态</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Animal &lt;= Cat</span>

animal = cat; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
cat = animal; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ERROR: cat 继承于 animal</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 演示每个数组形式</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> animalArr: Animal[] = [animal];
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> catArr: Cat[] = [cat];

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 明显的坏处，逆变</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Animal &lt;= Cat</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Animal[] &gt;= Cat[]</span>
catArr = animalArr; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok, 如有有逆变</span>
catArr[<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>].meow(); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 允许，但是会在运行时报错</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 另外一个坏处，协变</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Animal &lt;= Cat</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Animal[] &lt;= Cat[]</span>
animalArr = catArr; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok，协变</span>

animalArr.push(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Animal(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'another animal'</span>)); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 仅仅是 push 一个 animal 至 carArr 里</span>
catArr.forEach(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">c</span> =&gt;</span> c.meow()); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 允许，但是会在运行时报错。</span>
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">Never</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">never 类型是 TypeScript 中的底层类型。它自然被分配的一些例子：</p>
<ul style="line-height: 160%; box-sizing: content-box; display: block; list-style-type: disc; padding-left: 30px; margin: 6px 0 10px; color: #333;">
<li style="line-height: 160%; box-sizing: content-box; position: relative;">一个从来不会有返回值的函数（如：如果函数内含有 while(true) {}）；</li>
<li style="line-height: 160%; box-sizing: content-box; position: relative;">一个总是会抛出错误的函数（如：function foo() { throw new Error('Not Implemented') }，foo 的返回类型是 never）；</li>
</ul>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你也可以将它用做类型注解：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: never; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">但是，never 类型仅能被赋值给另外一个 never：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: never = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: number 类型不能赋值给 never 类型</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok, 作为函数返回类型的 never</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar: never = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"/>) =&gt; {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">throw</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Error</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">'Throw my hands <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">in</span> the air like I just dont care'</span>);
}</span>)<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">()</span>;
</span></code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">用例：详细的检查</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">foo</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> | <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">boolean</span> </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> x === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'string'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">true</span>;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> x === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'number'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">false</span>;
  }

  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如果不是一个 never 类型，这会报错：</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// - 不是所有条件都有返回值 （严格模式下）</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// - 或者检查到无法访问的代码</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 但是由于 TypeScript 理解 `fail` 函数返回为 `never` 类型</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 它可以让你调用它，因为你可能会在运行时用它来做安全或者详细的检查。</span>
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> fail(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Unexhaustive'</span>);
}

<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">fail</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">message: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span></span>): <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">never</span> </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">throw</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Error</span>(message);
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">与 void 的差异</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">一旦有人告诉你，never 表示一个从来不会优雅的返回的函数时，你可能马上就会想到与此类似的 void，然而实际上，void 表示没有任何类型，never 表示永远不存在的值的类型。<br/>
void 指可以被赋值的类型（在 strictNullChecking 为 false 时），其他任何类型不能赋值给 never，除了 never 本身以外。</p>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">辨析联合类型</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当类中含有字面量成员时，我们可以用该类的属性来辨析联合类型。<br/>
作为一个例子，考虑 Square 和 Rectangle 的联合类型 Shape。Square 和 Rectangle有共同成员 kind，因此 kind 存在于 Shape 中。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Square {
  kind: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'square'</span>;
  size: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Rectangle {
  kind: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'rectangle'</span>;
  width: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  height: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Shape = Square | Rectangle;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如果你使用类型保护风格的检查（==、===、!=、!==）或者使用具有判断性的属性（在这里是 kind），TypeScript 将会认为你会使用的对象类型一定是拥有特殊字面量的，并且它会为你自动把类型范围变小：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">area</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">s: Shape</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (s.kind === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'square'</span>) {
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 现在 TypeScript 知道 s 的类型是 Square</span>
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 所以你现在能安全使用它</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.size * s.size;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 不是一个 square ？因此 TypeScript 将会推算出 s 一定是 Rectangle</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.width * s.height;
  }
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">详细的检查</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Square {
  kind: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'square'</span>;
  size: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Rectangle {
  kind: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'rectangle'</span>;
  width: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  height: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 有人仅仅是添加了 `Circle` 类型</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 我们可能希望 TypeScript 能在任何被需要的地方抛出错误</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Circle {
  kind: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'circle'</span>;
  radius: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Shape = Square | Rectangle | Circle;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">一个可能会让你的代码变差的例子：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">area</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">s: Shape</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (s.kind === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'square'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.size * s.size;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (s.kind === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'rectangle'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.width * s.height;
  }

  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 如果你能让 TypeScript 给你一个错误，这是不是很棒？</span>
}

</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以通过一个简单的向下思想，来确保块中的类型被推断为与 never 类型兼容的类型。例如，你可以添加一个更详细的检查来捕获错误：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">area</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">s: Shape</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (s.kind === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'square'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.size * s.size;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (s.kind === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'rectangle'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.width * s.height;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'Circle' 不能被赋值给 'never'</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> _exhaustiveCheck: never = s;
  }
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">它将强制你添加一种新的条件：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">area</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">s: Shape</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (s.kind === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'square'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.size * s.size;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (s.kind === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'rectangle'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.width * s.height;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (s.kind === <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'circle'</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Math</span>.PI * s.radius ** <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span>;
  } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
    <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> _exhaustiveCheck: never = s;
  }
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">Switch</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以通过 switch 来实现以上例子。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">area</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">s: Shape</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">switch</span> (s.kind) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'square'</span>:
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.size * s.size;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'rectangle'</span>:
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.width * s.height;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'circle'</span>:
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Math</span>.PI * s.radius ** <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span>;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">default</span>:
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> _exhaustiveCheck: never = s;
  }
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">strictNullChecks</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如果你使用 strictNullChecks 选项来做详细的检查，你应该返回 _exhaustiveCheck 变量（类型是 never），否则 TypeScript 可能会推断返回值为 undefined：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">area</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">s: Shape</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">switch</span> (s.kind) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'square'</span>:
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.size * s.size;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'rectangle'</span>:
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> s.width * s.height;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">case</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'circle'</span>:
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Math</span>.PI * s.radius ** <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span>;
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">default</span>:
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> _exhaustiveCheck: never = s;
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> _exhaustiveCheck;
  }
}
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">索引签名</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">可以用字符串访问 JavaScript 中的对象（TypeScript 中也一样），用来保存对其他对象的引用。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Foo {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">constructor</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">public</span> message: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span></span>) {}
  log() {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.message);
  }
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span> = {};
foo[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span>] = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> Foo(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'World'</span>);
foo[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span>].log(); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// World</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当你传入一个其他对象至索引签名时，JavaScript 会在得到结果之前会先调用 .toString 方法：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//只要索引位置使用了 obj，toString 方法都将会被调用。</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> obj = {
  toString() {
    <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'toString called'</span>);
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span>;
  }
};

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span> = {};
foo[obj] = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'World'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// toString called</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(foo[obj]); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// toString called, World</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(foo[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span>]); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// World</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><u style="line-height: 160%; box-sizing: content-box;">数组有点稍微不同，对于一个 number 类型的索引签名，JavaScript 引擎将会尝试去优化（这取决于它是否是一个真的数组、存储的项目结构是否匹配等）。因此，number 应该被考虑作为一个有效的对象访问器（这与 string 不同），如下例子</u></p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo = [<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'World'</span>];
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(foo[<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span>]); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// World</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">TypeScript 索引签名</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">JavaScript 在一个对象类型的索引签名上会隐式调用 toString 方法，而在 TypeScript 中，为防止初学者砸伤自己的脚（我总是看到 stackoverflow 上有很多 JavaScript 使用者都会这样。），它将会抛出一个错误。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> obj = {
  toString() {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span>;
  }
};

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span> = {};

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ERROR: 索引签名必须为 string, number....</span>
foo[obj] = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'World'</span>;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// FIX: TypeScript 强制你必须明确这么做：</span>
foo[obj.toString()] = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'World'</span>;
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">强制用户必须明确的写出 toString() 的原因是：在对象上默认执行的 toString 方法是有害的。例如 v8 引擎上总是会返回 [object Object]</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> obj = { message: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello'</span> };
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span> = {};

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ERROR: 索引签名必须为 string, number....</span>
foo[obj] = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'World'</span>;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 这里实际上就是你存储的地方</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(foo[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'[object Object]'</span>]); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// World</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">TypeScript 的索引签名必须是 string 或者 number。<br/>
symbols 也是有效的，TypeScript 支持它。</em></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">声明一个索引签名</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">我们可以明确的指定索引签名。例如：假设你想确认存储在对象中任何内容都符合 { message: string } 的结构，你可以通过 [index: string]: { message: string } 来实现。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo: {
  [index: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>]: { message: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> };
} = {};

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 储存的东西必须符合结构</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
foo[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'a'</span>] = { message: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'some message'</span> };

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error, 必须包含 `message`</span>
foo[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'a'</span>] = { messages: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'some message'</span> };

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 读取时，也会有类型检查</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
foo[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'a'</span>].message;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: messages 不存在</span>
foo[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'a'</span>].messages;
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">所有成员都必须符合字符串的索引签名</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当你声明一个索引签名时，所有明确的成员都必须符合索引签名：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Foo {
  [key: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>]: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> Bar {
  [key: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>]: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: y 属性必须为 number 类型</span>
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">使用一组有限的字符串字面量</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">一个索引签名可以通过映射类型来使索引字符串为联合类型中的一员，如下所示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Index = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'a'</span> | <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'b'</span> | <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'c'</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> FromIndex = { [k <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">in</span> Index]?: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span> };

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> good: FromIndex = { b: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, c: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span> };

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error:</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// `{ b: 1, c: 2, d: 3 }` 不能分配给 'FromIndex'</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 对象字面量只能指定已知类型，'d' 不存在 'FromIndex' 类型上</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> bad: FromIndex = { b: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>, c: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">2</span>, d: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">3</span> };
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">变量的规则一般可以延迟被推断：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> FromSomeIndex&lt;K <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">extends</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>&gt; = { [key <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">in</span> K]: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span> };
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">同时拥有 string 和 number 类型的索引签名</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">string 类型的索引签名比 number 类型的索引签名更严格。这是故意设计，它允许你有如下类型：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> ArrStr {
  [key: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>]: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> | <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 必须包括所用成员类型</span>
  [index: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>]: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 字符串索引类型的子级</span>

  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// example</span>
  length: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">设计模式：索引签名的嵌套</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> NestedCSS {
  color?: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// strictNullChecks=false 时索引签名可为 undefined</span>
  [selector: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>]: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> | NestedCSS;
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> example: NestedCSS = {
  color: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'red'</span>,
  <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'.subclass'</span>: {
    color: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'blue'</span>
  }
};

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//尽量不要使用这种把字符串索引签名与有效变量混合使用。如果属性名称中有拼写错误，这个错误不会被捕获到：</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> failsSilently: NestedCSS = {
  colour: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'red'</span> <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 'colour' 不会被捕捉到错误</span>
};

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//取而代之，我们把索引签名分离到自己的属性里，如命名为 nest（或者 children、subnodes 等）：</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">interface</span> NestedCSS {
  color?: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
  nest?: {
    [selector: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>]: NestedCSS;
  };
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> example: NestedCSS = {
  color: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'red'</span>,
  nest: {
    <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'.subclass'</span>: {
      color: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'blue'</span>
    }
  }
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> failsSliently: NestedCSS {
  colour: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'red'</span>  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// TS Error: 未知属性 'colour'</span>
}
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">流动的类型</h2>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">复制类型和值</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">如果你想移动一个类，你可能会想要做以下事情：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Foo {}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> Bar = Foo;

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar: Bar; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 不能找到名称 'Bar'</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">因为 const 仅仅是复制了 Foo 到一个变量声明空间，因此你无法把 Bar 当作一个类型声明使用。正确的方式是使用 import 关键字，请注意，如果你在使用 namespace 或者 modules，使用 import 是你唯一能用的方式：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">namespace</span> importing {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">export</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Foo {}
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">import</span> Bar = importing.Foo;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar: Bar; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><em style="line-height: 160%; box-sizing: content-box; font-style: italic;">这个 import 技巧，仅适合于类型和变量。</em></p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">捕获变量的类型</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以通过 typeof 操作符在类型注解中使用变量。这允许你告诉编译器，一个变量的类型与其他类型相同，如下所示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">123</span>;
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar: <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> foo; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 'bar' 类型与 'foo' 类型相同（在这里是： 'number'）</span>

bar = <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">456</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
bar = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'789'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error: 'string' 不能分配给 'number' 类型</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">捕获类成员的类型</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">与捕获变量的类型相似，你仅仅是需要声明一个变量用来捕获到的类型：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> Foo {
  foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 我们想要捕获的类型</span>
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">declare</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> _foo: Foo;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 与之前做法相同</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar: <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> _foo.foo;
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">捕获字符串类型</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">许多 JavaScript 库和框架都使用原始的 JavaScript 字符串，你可以使用 const 定义一个变量捕获它的类型：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 捕获字符串的类型与值</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello World'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//字面量类型</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 使用一个捕获的类型</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar: <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> foo;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// bar 仅能被赋值 'Hello World'  </span>
bar = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Hello World'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
bar = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'anything else'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">捕获键的名称</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">keyof 操作符能让你捕获一个类型的键。例如，你可以使用它来捕获变量的键名称，在通过使用 typeof 来获取类型之后：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> colors = {
  red: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'red'</span>,
  blue: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'blue'</span>
};

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Colors = keyof <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">typeof</span> colors;

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> color: Colors; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// color 的类型是 'red' | 'blue'</span>
color = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'red'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
color = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'blue'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ok</span>
color = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'anythingElse'</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Error</span>
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">异常处理</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">JavaScript 有一个 Error 类，用于处理异常。你可以通过 throw 关键字来抛出一个错误。然后通过 try/catch 块来捕获此错误：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">try</span> {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">throw</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Error</span>(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Something bad happened'</span>);
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">catch</span> (e) {
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(e);
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">错误子类型</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">除内置的 Error 类外，还有一些额外的内置错误，它们继承自 Error 类：</p>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">RangeError</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当数字类型变量或者参数超出其有效范围时，出现 RangeError 的错误提示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 使用过多参数调用 console</span>
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log.apply(<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>, <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Array</span>(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1000000000</span>)); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// RangeError: 数组长度无效</span>
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">ReferenceError</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当引用无效时，会出现 ReferenceError 的错误提示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #9b9b9b; line-height: 160%; box-sizing: content-box;">'use strict'</span>;
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(notValidVar); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ReferenceError: notValidVar 未定义</span>
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">SyntaxError</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当解析无效 JavaScript 代码时，会出现 SyntaxError 的错误提示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span> *** <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">3</span>   <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// SyntaxError: 无效的标记 *</span>
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">TypeError</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">变量或者参数不是有效类型时，会出现 TypeError 的错误提示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'1.2'</span>.toPrecision(<span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">1</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// TypeError: '1.2'.toPrecision 不是函数。</span>
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">URIError</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">当传入无效参数至 encodeURI() 和 decodeURI() 时，会出现 URIError 的错误提示：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">decodeURI</span>(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'%'</span>); <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// URIError: URL 异常</span>
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">使用 Error</h4>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;">try {
  throw 'Something bad happened';
} catch (e) {
  console.log(e);
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;"><strong style="line-height: 160%; box-sizing: content-box; font-weight: 700;">不要这么做</strong>，使用 Error 对象的基本好处是，它能自动跟踪堆栈的属性构建以及生成位置。<br/>
原始字符串会导致极差的调试体验，并且在分析日志时，将会变得错综复杂。</p>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">你并不需要 throw 抛出一个错误</h4>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">传递一个 Error 对象是没问题的，这种方式在 Node.js 回调函数中非常常见，它用第一个参数作为错误对象进行回调处理。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">myFunction</span> (<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">callback: (e: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Error</span>)</span>) </span>{
  doSomethingAsync(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> (<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"/>) </span>{
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (somethingWrong) {
      callback(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Error</span>(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'This is my error'</span>));
    } <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">else</span> {
      callback();
    }
  })
}
</code></pre>
<h4 style="line-height: 160%; box-sizing: content-box; font-size: 20px; color: #333;">优秀的用例</h4>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">不清楚从哪里抛出错误</h5>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">try</span> {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = runTask1();
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> bar = runTask2();
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">catch</span> (e) {
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Error:'</span>, e);
}
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//下一个开发者可能并不清楚哪个函数可能会抛出错误。在没有阅读 task1/task2 代码以及他们可能会调用的函数时，对代码 review 的人员可能也不会知道错误会从哪里抛出。</span>
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">优雅的捕获错误</h5>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">你可以通过为每个可能抛出错误的代码显式捕获，来使其优雅：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">try</span> {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> foo = runTask1();
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">catch</span> (e) {
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Error:'</span>, e);
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">try</span> {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> bar = runTask2();
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">catch</span> (e) {
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Error:'</span>, e);
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">但是现在，如果你想从第一个任务中传递变量到第二个任务中，代码会变的混乱（注意：foo 变量需要用 let 显式注解它，因为它不能从 runTask1 中返回出来）：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Notice 使用 let 并且显式注明类型注解</span>

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">try</span> {
  foo = runTask1();
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">catch</span> (e) {
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Error:'</span>, e);
}

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">try</span> {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> bar = runTask2(foo);
} <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">catch</span> (e) {
  <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Error:'</span>, e);
}
</code></pre>
<h5 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 16px; color: #333;">没有在类型系统中很好的表示</h5>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">validate</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">value: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span></span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (value &lt; <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> || value &gt; <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">100</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">throw</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Error</span>(<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Invalid value'</span>);
  }
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">在这种情境下使用 Error 不是一个好的主意。因为没有用来验证函数的类型定义（如：(value: number) =&gt; void），取而代之一个更好的方式是创建一个验证方法：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">validate</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">
  value: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>
</span>): </span>{
  error?: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span>;
} {
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">if</span> (value &lt; <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">0</span> || value &gt; <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">100</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> { error: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'Invalid value'</span> };
  }
}
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">混合</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">TypeScript (和 JavaScript) 类只能严格的单继承，因此你不能做：</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> User <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">extends</span> Tagged, Timestamped { <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ERROR : 不能多重继承</span>
  <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// ..</span>
}
</code></pre>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">采用函数 B 接受一个类 A，并且返回一个带有新功能的类的方式来替代 A 类扩展 B 来获取 B 上的功能，前者中的 B 即是混合。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">「混合」是一个函数：</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">1、传入一个构造函数；<br/>
2、创建一个带有新功能，并且扩展构造函数的新类；<br/>
3、返回这个新类。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 所有 mixins 都需要</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Constructor&lt;T = {}&gt; = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> (...args: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">any</span>[]) =&gt; T;

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">/////////////</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// mixins 例子</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">////////////</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 添加属性的混合例子</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">TimesTamped</span>&lt;<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">TBase</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">extends</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Constructor</span>&gt;(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Base: TBase</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">extends</span> Base {
    timestamp = <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">Date</span>.now();
  };
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 添加属性和方法的混合例子</span>
<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Activatable</span>&lt;<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">TBase</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">extends</span> <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Constructor</span>&gt;(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">Base: TBase</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">extends</span> Base {
    isActivated = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">false</span>;

    activate() {
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.isActivated = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">true</span>;
    }

    deactivate() {
      <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.isActivated = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">false</span>;
    }
  };
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">///////////</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 组合类</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">///////////</span>

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 简单的类</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">class</span> User {
  name = <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">''</span>;
}

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 添加 TimesTamped 的 User</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> TimestampedUser = TimesTamped(User);

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Tina TimesTamped 和 Activatable 的类</span>
<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> TimestampedActivatableUser = TimesTamped(Activatable(User));

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//////////</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 使用组合类</span>
<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//////////</span>

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> timestampedUserExample = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> TimestampedUser();
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(timestampedUserExample.timestamp);

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">const</span> timestampedActivatableUserExample = <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">new</span> TimestampedActivatableUser();
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(timestampedActivatableUserExample.timestamp);
<span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">console</span>.log(timestampedActivatableUserExample.isActivated);
</code></pre>
<h2 style="line-height: 160%; box-sizing: content-box; font-weight: 700; font-size: 34px; border-bottom: 1px solid #dbdbdb; color: #333;">ThisType</h2>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">通过 ThisType 我们可以在对象字面量中键入 this，并提供通过上下文类型控制 this 类型的便捷方式。它只有在 --noImplicitThis 的选项下才有效。</p>
<p style="line-height: 160%; box-sizing: content-box; margin: 10px 0; color: #333;">现在，在对象字面量方法中的 this 类型，将由以下决定：<br/>
1、如果这个方法显示指定了 this 参数，那么 this 具有该参数的类型。（下例子中 bar）<br/>
2、否则，如果方法由带 this 参数的签名进行上下文键入，那么 this 具有该参数的类型。（下例子中 foo）<br/>
3、否则，如果 --noImplicitThis 选项已经启用，并且对象字面量中包含由 ThisType&lt;T&gt; 键入的上下文类型，那么 this 的类型为 T。<br/>
4、否则，如果 --noImplicitThis 选项已经启用，并且对象字面量中不包含由 ThisType&lt;T&gt; 键入的上下文类型，那么 this 的类型为该上下文类型。<br/>
5、否则，如果 --noImplicitThis 选项已经启用，this 具有该对象字面量的类型。<br/>
6、否则，this 的类型为 any。</p>
<pre style="line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; margin: 2px 0 8px; background-color: #f5f7f8;"><code style="display: block; overflow-x: auto; background: #1e1e1e; line-height: 160%; box-sizing: content-box; border: 0; border-radius: 0; letter-spacing: -.3px; padding: 18px; color: #f4f4f4; white-space: pre-wrap;"><span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// Compile with --noImplicitThis</span>

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">type</span> Point = {
  x: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  y: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>;
  moveBy(dx: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>, dy: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>): <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">void</span>;
};

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> p: Point = {
  x: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">10</span>,
  y: <span style="color: #b8d7a3; line-height: 160%; box-sizing: content-box;">20</span>,
  moveBy(dx, dy) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.x += dx; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// this has type Point</span>
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.y += dy; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// this has type Point</span>
  }
};

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> foo = {
  x: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span>,
  f(n: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">number</span>) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// { x: string, f(n: number): void }</span>
  }
};

<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">let</span> bar = {
  x: <span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'hello'</span>,
  f(<span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>: { message: <span style="color: #4ec9b0; line-height: 160%; box-sizing: content-box;">string</span> }) {
    <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// { message: string }</span>
  }
};

<span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">//函数表达式赋值给 obj.xxx 或者 obj[xxx] 的目标时，在函数中 this 的类型将会是 obj：</span>
obj.f = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">n</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.x - n; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 'this' has same type as 'obj'</span>
};

obj[<span style="color: #d69d85; line-height: 160%; box-sizing: content-box;">'f'</span>] = <span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;"><span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">function</span>(<span style="color: #dcdcdc; line-height: 160%; box-sizing: content-box;">n</span>) </span>{
  <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">return</span> <span style="color: #569cd6; line-height: 160%; box-sizing: content-box;">this</span>.x - n; <span style="color: #57a64a; font-style: italic; line-height: 160%; box-sizing: content-box;">// 'this' has same type as 'obj'</span>
};
</code></pre>
</div><center style="display:none !important;visibility:collapse !important;height:0 !important;white-space:nowrap;width:100%;overflow:hidden">%23%23%20%40types%0A%23%23%23%23%20%E4%BD%BF%E7%94%A8%20%40types%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%20npm%20%E6%9D%A5%E5%AE%89%E8%A3%85%E4%BD%BF%E7%94%A8%20%40types%EF%BC%8C%E4%BE%8B%E5%A6%82%E4%B8%BA%20jquery%20%E6%B7%BB%E5%8A%A0%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6%EF%BC%9A%0A%60%60%60%0Anpm%20install%20%40types%2Fjquery%20--save-dev%0A%60%60%60%0A%0A%23%23%23%23%20%E5%85%A8%E5%B1%80%20%40types%0A%E9%BB%98%E8%AE%A4%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8CTypeScript%20%E4%BC%9A%E8%87%AA%E5%8A%A8%E5%8C%85%E5%90%AB%E6%94%AF%E6%8C%81%E5%85%A8%E5%B1%80%E4%BD%BF%E7%94%A8%E7%9A%84%E4%BB%BB%E4%BD%95%E5%A3%B0%E6%98%8E%E5%AE%9A%E4%B9%89%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%8C%E5%AF%B9%E4%BA%8E%20jquery%EF%BC%8C%E4%BD%A0%E5%BA%94%E8%AF%A5%E8%83%BD%E5%A4%9F%E5%9C%A8%E9%A1%B9%E7%9B%AE%E4%B8%AD%E5%BC%80%E5%A7%8B%E5%85%A8%E5%B1%80%E4%BD%BF%E7%94%A8%20%24%E3%80%82%0A%0A%0A%23%23%23%23%20%E6%A8%A1%E5%9D%97%20%40types%0A%E5%AE%89%E8%A3%85%E5%AE%8C%E4%B9%8B%E5%90%8E%EF%BC%8C%E4%B8%8D%E9%9C%80%E8%A6%81%E7%89%B9%E5%88%AB%E7%9A%84%E9%85%8D%E7%BD%AE%EF%BC%8C%E4%BD%A0%E5%B0%B1%E5%8F%AF%E4%BB%A5%E5%83%8F%E4%BD%BF%E7%94%A8%E6%A8%A1%E5%9D%97%E4%B8%80%E6%A0%B7%E4%BD%BF%E7%94%A8%E5%AE%83%EF%BC%9A%0A%60%60%60%0Aimport%20*%20as%20%24%20from%20'jquery'%3B%0A%0A%2F%2F%20%E7%8E%B0%E5%9C%A8%E4%BD%A0%E5%8F%AF%E4%BB%A5%E6%AD%A4%E6%A8%A1%E5%9D%97%E4%B8%AD%E4%BB%BB%E6%84%8F%E4%BD%BF%E7%94%A8%24%E4%BA%86%20%3A)%0A%60%60%60%0A%0A%23%23%23%23%20%E6%8E%A7%E5%88%B6%E5%85%A8%E5%B1%80%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E9%85%8D%E7%BD%AE%20tsconfig.json%20%E7%9A%84%20compilerOptions.types%20%E9%80%89%E9%A1%B9%EF%BC%8C%E5%BC%95%E5%85%A5%E6%9C%89%E6%84%8F%E4%B9%89%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%9A%0A%60%60%60%0A%7B%0A%20%20%22compilerOptions%22%3A%20%7B%0A%20%20%20%20%22types%22%20%3A%20%5B%0A%20%20%20%20%20%20%22jquery%22%0A%20%20%20%20%5D%0A%20%20%7D%0A%7D%0A%60%60%60%0A%E5%A6%82%E4%B8%8A%E4%BE%8B%E6%89%80%E7%A4%BA%EF%BC%8C%E9%80%9A%E8%BF%87%E9%85%8D%E7%BD%AE%20compilerOptions.types%3A%20%5B%20%22jquery%22%20%5D%20%E5%90%8E%EF%BC%8C%E5%8F%AA%E5%85%81%E8%AE%B8%E4%BD%BF%E7%94%A8%20jquery%20%E7%9A%84%20%40types%20%E5%8C%85%EF%BC%8C%E5%8D%B3%E4%BD%BF%E8%BF%99%E4%B8%AA%E4%BA%BA%E5%AE%89%E8%A3%85%E4%BA%86%E5%8F%A6%E4%B8%80%E4%B8%AA%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6%EF%BC%8C%E6%AF%94%E5%A6%82%20npm%20install%20%40types%2Fnode%EF%BC%8C%E5%AE%83%E7%9A%84%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%EF%BC%88%E4%BE%8B%E5%A6%82%20process%EF%BC%89%E4%B9%9F%E4%B8%8D%E4%BC%9A%E6%B3%84%E6%BC%8F%E5%88%B0%E4%BD%A0%E7%9A%84%E4%BB%A3%E7%A0%81%E4%B8%AD%EF%BC%8C%E7%9B%B4%E5%88%B0%E4%BD%A0%E5%B0%86%E5%AE%83%E4%BB%AC%E6%B7%BB%E5%8A%A0%E5%88%B0%20tsconfig.json%20%E7%B1%BB%E5%9E%8B%E9%80%89%E9%A1%B9%E3%80%82%0A%0A%23%23%20%E7%8E%AF%E5%A2%83%E5%A3%B0%E6%98%8E%0A%E7%8E%AF%E5%A2%83%E5%A3%B0%E6%98%8E%E5%85%81%E8%AE%B8%E4%BD%A0%E5%AE%89%E5%85%A8%E7%9A%84%E4%BD%BF%E7%94%A8%E7%8E%B0%E6%9C%89%E7%9A%84%20JavaScript%20%E5%BA%93%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%83%BD%E8%AE%A9%E4%BD%A0%E7%9A%84%20JavaScript%E3%80%81CoffeeScript%20%E6%88%96%E8%80%85%E5%85%B6%E4%BB%96%E9%9C%80%E8%A6%81%E7%BC%96%E8%AF%91%E6%88%90%20JavaScript%20%E7%9A%84%E8%AF%AD%E8%A8%80%E9%80%90%E6%AD%A5%E8%BF%81%E7%A7%BB%E8%87%B3%20TypeScript%E3%80%82%0A%E5%AD%A6%E4%B9%A0%E4%B8%BA%E7%AC%AC%E4%B8%89%E6%96%B9%20JavaScript%20%E5%BA%93%E7%BC%96%E5%86%99%E7%8E%AF%E5%A2%83%E5%A3%B0%E6%98%8E%EF%BC%8C%E6%98%AF%E4%B8%80%E7%A7%8D%E4%B8%BA%20TypeScript%20%E5%86%99%E6%B3%A8%E8%A7%A3%E6%AF%94%E8%BE%83%E5%A5%BD%E7%9A%84%E5%AE%9E%E8%B7%B5%E6%96%B9%E5%BC%8F%E3%80%82%0A%0A%23%23%23%23%20%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6%0A%0A%60%60%60js%0Afoo%20%3D%20123%3B%20%2F%2F%20Error%3A%20'foo'%20is%20not%20defined%0A%0A%0Adeclare%20var%20foo%3A%20any%3B%0Afoo%20%3D%20123%3B%20%2F%2F%20allow%0A%60%60%60%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%89%E6%8B%A9%E6%8A%8A%E8%BF%99%E4%BA%9B%E5%A3%B0%E6%98%8E%E6%94%BE%E5%85%A5%20.ts%20%E6%88%96%E8%80%85%20.d.ts%20%E9%87%8C%E3%80%82%E5%9C%A8%E4%BD%A0%E5%AE%9E%E9%99%85%E7%9A%84%E9%A1%B9%E7%9B%AE%E9%87%8C%EF%BC%8C%E6%88%91%E4%BB%AC%E5%BC%BA%E7%83%88%E5%BB%BA%E8%AE%AE%E4%BD%A0%E5%BA%94%E8%AF%A5%E6%8A%8A%E5%A3%B0%E6%98%8E%E6%94%BE%E5%85%A5%E7%8B%AC%E7%AB%8B%E7%9A%84%20.d.ts%20%E9%87%8C%EF%BC%88%E5%8F%AF%E4%BB%A5%E4%BB%8E%E4%B8%80%E4%B8%AA%E5%91%BD%E5%90%8D%E4%B8%BA%20global.d.ts%20%E6%88%96%E8%80%85%20vendor.d.ts%20%E6%96%87%E4%BB%B6%E5%BC%80%E5%A7%8B%EF%BC%89%E3%80%82%0A%0A%E5%A6%82%E6%9E%9C%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E6%9C%89%E6%89%A9%E5%B1%95%E5%90%8D%20.d.ts%EF%BC%8C%E8%BF%99%E6%84%8F%E5%91%B3%E7%9D%80%E6%AF%8F%E4%B8%AA%E6%A0%B9%E7%BA%A7%E5%88%AB%E7%9A%84%E5%A3%B0%E6%98%8E%E9%83%BD%E5%BF%85%E9%A1%BB%E4%BB%A5%20declare%20%E5%85%B3%E9%94%AE%E5%AD%97%E4%BD%9C%E4%B8%BA%E5%89%8D%E7%BC%80%E3%80%82%E8%BF%99%E6%9C%89%E5%88%A9%E4%BA%8E%E8%AE%A9%E5%BC%80%E5%8F%91%E8%80%85%E6%B8%85%E6%A5%9A%E7%9A%84%E7%9F%A5%E9%81%93%EF%BC%8C%E5%9C%A8%E8%BF%99%E9%87%8C%20TypeScript%20%E5%B0%86%E4%B8%8D%E4%BC%9A%E6%8A%8A%E5%AE%83%E7%BC%96%E8%AF%91%E6%88%90%E4%BB%BB%E4%BD%95%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%90%8C%E6%97%B6%E5%BC%80%E5%8F%91%E8%80%85%E9%9C%80%E8%A6%81%E7%A1%AE%E4%BF%9D%E8%BF%99%E4%BA%9B%E5%9C%A8%E7%BC%96%E8%AF%91%E6%97%B6%E5%AD%98%E5%9C%A8%E3%80%82%0A%0A%23%23%23%23%20%E5%8F%98%E9%87%8F%0A%E5%BD%93%E4%BD%A0%E6%83%B3%E5%91%8A%E8%AF%89%20TypeScript%20%E7%BC%96%E8%BE%91%E5%99%A8%E5%85%B3%E4%BA%8E%20process%20%E5%8F%98%E9%87%8F%E6%97%B6%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E8%BF%99%E4%B9%88%E5%81%9A%EF%BC%9A%0A%60%60%60js%0Adeclare%20let%20process%3A%20any%3B%0A%0A%2F%2F%E8%BF%99%E5%85%81%E8%AE%B8%E4%BD%A0%E4%BD%BF%E7%94%A8%20process%EF%BC%8C%E5%B9%B6%E8%83%BD%E6%88%90%E5%8A%9F%E9%80%9A%E8%BF%87%20TypeScript%20%E7%9A%84%E7%BC%96%E8%AF%91%EF%BC%9A%0Aprocess.exit()%3B%0A%60%60%60%0A%0A%E6%88%91%E4%BB%AC%E6%8E%A8%E8%8D%90%E5%B0%BD%E5%8F%AF%E8%83%BD%E7%9A%84%E4%BD%BF%E7%94%A8%E6%8E%A5%E5%8F%A3%EF%BC%8C%E4%BE%8B%E5%A6%82%EF%BC%9A%0A%60%60%60js%0Ainterface%20Process%20%7B%0A%20%20exit(code%3F%3A%20number)%3A%20void%3B%0A%7D%0A%0Adeclare%20let%20process%3A%20Process%3B%0A%0A%2F%2F%E5%9B%A0%E4%B8%BA%E8%BF%99%E5%85%81%E8%AE%B8%E5%85%B6%E4%BB%96%E4%BA%BA%E6%89%A9%E5%85%85%E8%BF%99%E4%BA%9B%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%EF%BC%8C%E5%B9%B6%E4%B8%94%E4%BC%9A%E5%91%8A%E8%AF%89%20TypeScript%20%E6%9C%89%E5%85%B3%E4%BA%8E%E8%BF%99%E4%BA%9B%E5%A3%B0%E6%98%8E%E7%9A%84%E4%BF%AE%E6%94%B9%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%9A%E8%80%83%E8%99%91%E5%88%B0%E4%BB%A5%E4%B8%8B%E6%83%85%E5%86%B5%EF%BC%8C%E6%88%91%E4%BB%AC%E6%B7%BB%E5%8A%A0%E4%B8%80%E4%B8%AA%20exitWithLogging%20%E5%87%BD%E6%95%B0%E8%87%B3%20process%EF%BC%9A%0A%0Ainterface%20Process%20%7B%0A%20%20exitWithLogging(code%3F%3A%20number)%3A%20void%3B%0A%7D%0A%0Aprocess.exitWithLogging%20%3D%20function()%20%7B%0A%20%20console.log('exiting')%3B%0A%20%20process.exit.apply(process%2C%20arguments)%3B%0A%7D%3B%0A%60%60%60%0A%0A%23%23%20%E6%8E%A5%E5%8F%A3%0A%E4%B8%8B%E9%9D%A2%E4%B8%A4%E4%B8%AA%E6%98%AF%E7%AD%89%E6%95%88%E7%9A%84%E5%A3%B0%E6%98%8E%2C%20%E7%A4%BA%E4%BE%8B%20A%20%E4%BD%BF%E7%94%A8%E5%86%85%E8%81%94%E6%B3%A8%E8%A7%A3%EF%BC%8C%E7%A4%BA%E4%BE%8B%20B%20%E4%BD%BF%E7%94%A8%E6%8E%A5%E5%8F%A3%E5%BD%A2%E5%BC%8F%EF%BC%9A%0A%60%60%60js%0A%2F%2F%20%E7%A4%BA%E4%BE%8B%20A%0Adeclare%20const%20myPoint%3A%20%7B%20x%3A%20number%3B%20y%3A%20number%20%7D%3B%0A%0A%2F%2F%20%E7%A4%BA%E4%BE%8B%20B%0Ainterface%20Point%20%7B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%7D%0Adeclare%20const%20myPoint%3A%20Point%3B%0A%60%60%60%0A%0A%E7%A4%BA%E4%BE%8B%20B%20%E7%9A%84%E5%A5%BD%E5%A4%84%E5%9C%A8%E4%BA%8E%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%9C%89%E4%BA%BA%E5%88%9B%E5%BB%BA%E4%BA%86%E4%B8%80%E4%B8%AA%E5%9F%BA%E4%BA%8E%20myPoint%20%E7%9A%84%E5%BA%93%E6%9D%A5%E6%B7%BB%E5%8A%A0%E6%96%B0%E6%88%90%E5%91%98%2C%20%E9%82%A3%E4%B9%88%E4%BB%96%E5%8F%AF%E4%BB%A5%E8%BD%BB%E6%9D%BE%E5%B0%86%E6%AD%A4%E6%88%90%E5%91%98%E6%B7%BB%E5%8A%A0%E5%88%B0%20myPoint%20%E7%9A%84%E7%8E%B0%E6%9C%89%E5%A3%B0%E6%98%8E%E4%B8%AD%3A%0A%60%60%60js%0A%2F%2F%20Lib%20a.d.ts%0Ainterface%20Point%20%7B%0A%20%20x%3A%20number%2C%0A%20%20y%3A%20number%0A%7D%0Adeclare%20const%20myPoint%3A%20Point%0A%0A%2F%2F%20Lib%20b.d.ts%0Ainterface%20Point%20%7B%0A%20%20z%3A%20number%0A%7D%0A%0A%2F%2F%20Your%20code%0AmyPoint.z%20%2F%2F%20Allowed!%0A%60%60%60%0A%0A%23%23%23%23%20%E7%B1%BB%E5%8F%AF%E4%BB%A5%E5%AE%9E%E7%8E%B0%E6%8E%A5%E5%8F%A3%0A%E5%A6%82%E6%9E%9C%E4%BD%A0%E5%B8%8C%E6%9C%9B%E5%9C%A8%E7%B1%BB%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%BF%85%E9%A1%BB%E8%A6%81%E8%A2%AB%E9%81%B5%E5%BE%AA%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%88%E7%B1%BB%EF%BC%89%E6%88%96%E5%88%AB%E4%BA%BA%E5%AE%9A%E4%B9%89%E7%9A%84%E5%AF%B9%E8%B1%A1%E7%BB%93%E6%9E%84%EF%BC%8C%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%20implements%20%E5%85%B3%E9%94%AE%E5%AD%97%E6%9D%A5%E7%A1%AE%E4%BF%9D%E5%85%B6%E5%85%BC%E5%AE%B9%E6%80%A7%EF%BC%9A%0A%60%60%60js%0Ainterface%20Point%20%7B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%20%20z%3A%20number%3B%20%2F%2F%20New%20member%0A%7D%0A%0Aclass%20MyPoint%20implements%20Point%20%7B%0A%20%20%2F%2F%20ERROR%20%3A%20missing%20member%20%60z%60%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E6%B3%A8%E6%84%8F%0A**%E5%B9%B6%E9%9D%9E%E6%AF%8F%E4%B8%AA%E6%8E%A5%E5%8F%A3%E9%83%BD%E6%98%AF%E5%BE%88%E5%AE%B9%E6%98%93%E5%AE%9E%E7%8E%B0%E7%9A%84**%0A%60%60%60js%0Ainterface%20Crazy%20%7B%0A%20%20new%20()%3A%20%7B%0A%20%20%20%20hello%3A%20number%3B%0A%20%20%7D%3B%0A%7D%0A%0Aclass%20CrazyClass%20implements%20Crazy%20%7B%0A%20%20constructor()%20%7B%0A%20%20%20%20return%20%7B%20hello%3A%20123%20%7D%3B%0A%20%20%7D%0A%7D%0A%0A%2F%2F%20Because%0Aconst%20crazy%20%3D%20new%20CrazyClass()%3B%20%2F%2F%20crazy%20would%20be%20%7B%20hello%3A123%20%7D%0A%60%60%60%0A%0A%23%23%20%E6%9E%9A%E4%B8%BE%0A%23%23%23%23%20%E6%95%B0%E5%AD%97%E7%B1%BB%E5%9E%8B%E6%9E%9A%E4%B8%BE%0A%60%60%60js%0Aenum%20Color%20%7B%0A%20%20Red%2C%0A%20%20Green%2C%0A%20%20Blue%0A%7D%0A%0Alet%20col%20%3D%20Color.Red%3B%0Acol%20%3D%200%3B%20%2F%2F%20%E6%9C%89%E6%95%88%E7%9A%84%EF%BC%8C%E8%BF%99%E4%B9%9F%E6%98%AF%20Color.Red%0A%0A%2F%2F%20%E7%B1%BB%E5%9E%8B%E5%AE%89%E5%85%A8%0Acol%20%3D%20'not%20a%20member%20of%20color'%3B%20%2F%2F%20Error%3A%20string%20%E4%B8%8D%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%20%60color%60%20%E7%B1%BB%E5%9E%8B%0A%60%60%60%0A%0A%60%60%60js%0Aenum%20Tristate%20%7B%0A%20%20False%2C%0A%20%20True%2C%0A%20%20Unknown%0A%7D%0A%0A%2F%2F%E7%BC%96%E8%AF%91%E5%90%8E%0Avar%20Tristate%3B%0A(function(Tristate)%20%7B%0A%20%20Tristate%5B(Tristate%5B'False'%5D%20%3D%200)%5D%20%3D%20'False'%3B%0A%20%20Tristate%5B(Tristate%5B'True'%5D%20%3D%201)%5D%20%3D%20'True'%3B%0A%20%20Tristate%5B(Tristate%5B'Unknown'%5D%20%3D%202)%5D%20%3D%20'Unknown'%3B%0A%7D)(Tristate%20%7C%7C%20(Tristate%20%3D%20%7B%7D))%3B%0A%0A%0Aconsole.log(Tristate%5B0%5D)%3B%20%2F%2F%20'False'%0Aconsole.log(Tristate%5B'False'%5D)%3B%20%2F%2F%200%0Aconsole.log(Tristate%5BTristate.False%5D)%3B%20%2F%2F%20'False'%20because%20%60Tristate.False%20%3D%3D%200%60%0A%60%60%60%0A%E5%85%88%E8%AE%A9%E6%88%91%E4%BB%AC%E8%81%9A%E7%84%A6%20Tristate%5BTristate%5B'False'%5D%20%3D%200%5D%20%3D%20'False'%20%E8%BF%99%E8%A1%8C%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%85%B6%E4%B8%AD%20Tristate%5B'False'%5D%20%3D%200%20%E7%9A%84%E6%84%8F%E6%80%9D%E6%98%AF%E5%B0%86%20Tristate%20%E5%AF%B9%E8%B1%A1%E9%87%8C%E7%9A%84%20False%20%E6%88%90%E5%91%98%E5%80%BC%E8%AE%BE%E7%BD%AE%E4%B8%BA%200%E3%80%82%E6%B3%A8%E6%84%8F%EF%BC%8CJavaScript%20%E8%B5%8B%E5%80%BC%E8%BF%90%E7%AE%97%E7%AC%A6%E8%BF%94%E5%9B%9E%E7%9A%84%E5%80%BC%E6%98%AF%E8%A2%AB%E8%B5%8B%E4%BA%88%E7%9A%84%E5%80%BC%EF%BC%88%E5%9C%A8%E6%AD%A4%E4%BE%8B%E5%AD%90%E4%B8%AD%E6%98%AF%200%EF%BC%89%EF%BC%8C%E5%9B%A0%E6%AD%A4%E4%B8%8B%E4%B8%80%E6%AC%A1%20JavaScript%20%E8%BF%90%E8%A1%8C%E6%97%B6%E6%89%A7%E8%A1%8C%E7%9A%84%E4%BB%A3%E7%A0%81%E6%98%AF%20Tristate%5B0%5D%20%3D%20'False'%E3%80%82%0A%0A%23%23%23%23%20%E6%94%B9%E5%8F%98%E4%B8%8E%E6%95%B0%E5%AD%97%E6%9E%9A%E4%B8%BE%E5%85%B3%E8%81%94%E7%9A%84%E6%95%B0%E5%AD%97%0A%60%60%60js%0A%2F%2F%E9%BB%98%E8%AE%A4%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E7%AC%AC%E4%B8%80%E4%B8%AA%E6%9E%9A%E4%B8%BE%E5%80%BC%E6%98%AF%200%EF%BC%8C%E7%84%B6%E5%90%8E%E6%AF%8F%E4%B8%AA%E5%90%8E%E7%BB%AD%E5%80%BC%E4%BE%9D%E6%AC%A1%E9%80%92%E5%A2%9E%201%EF%BC%9A%0Aenum%20Color%20%7B%0A%20%20Red%2C%20%2F%2F%200%0A%20%20Green%2C%20%2F%2F%201%0A%20%20Blue%20%2F%2F%202%0A%7D%0A%0A%2F%2F%E4%BD%86%E6%98%AF%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E7%89%B9%E5%AE%9A%E7%9A%84%E8%B5%8B%E5%80%BC%E6%9D%A5%E6%94%B9%E5%8F%98%E7%BB%99%E4%BB%BB%E4%BD%95%E6%9E%9A%E4%B8%BE%E6%88%90%E5%91%98%E5%85%B3%E8%81%94%E7%9A%84%E6%95%B0%E5%AD%97%0Aenum%20Color%20%7B%0A%20%20DarkRed%20%3D%203%2C%20%2F%2F%203%0A%20%20DarkGreen%2C%20%2F%2F%204%0A%20%20DarkBlue%20%2F%2F%205%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E4%BD%BF%E7%94%A8%E6%95%B0%E5%AD%97%E7%B1%BB%E5%9E%8B%E4%BD%9C%E4%B8%BA%E6%A0%87%E5%BF%97%0A%E5%BD%93%E4%BD%A0%E5%9C%A8%E4%BD%BF%E7%94%A8%E8%BF%99%E7%A7%8D%E6%A0%87%E8%AE%B0%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E8%BF%99%E4%BA%9B%E4%BD%8D%E8%BF%90%E7%AE%97%E7%AC%A6%20%7C%20(%E6%88%96)%E3%80%81%26%20%EF%BC%88%E5%92%8C%EF%BC%89%E3%80%81~%20%EF%BC%88%E9%9D%9E%EF%BC%89%E5%B0%86%E4%BC%9A%E6%98%AF%E4%BD%A0%E6%9C%80%E5%A5%BD%E7%9A%84%E6%9C%8B%E5%8F%8B%EF%BC%9A%0A%60%60%60js%0Aenum%20AnimalFlags%20%7B%0A%20%20None%20%20%20%20%20%20%20%20%3D%200%2C%0A%20%20HasClaws%20%20%20%20%3D%201%20%3C%3C%200%2C%0A%20%20CanFly%20%20%20%20%20%20%3D%201%20%3C%3C%201%0A%7D%0A%0Ainterface%20Animal%20%7B%0A%20%20flags%3A%20AnimalFlags%3B%0A%20%20%5Bkey%3A%20string%5D%3A%20any%3B%0A%7D%0A%0Afunction%20printAnimalAbilities(animal%3A%20Animal)%20%7B%0A%20%20var%20animalFlags%20%3D%20animal.flags%3B%0A%20%20if%20(animalFlags%20%26%20AnimalFlags.HasClaws)%20%7B%0A%20%20%20%20console.log('animal%20has%20claws')%3B%0A%20%20%7D%0A%20%20if%20(animalFlags%20%26%20AnimalFlags.CanFly)%20%7B%0A%20%20%20%20console.log('animal%20can%20fly')%3B%0A%20%20%7D%0A%20%20if%20(animalFlags%20%3D%3D%20AnimalFlags.None)%20%7B%0A%20%20%20%20console.log('nothing')%3B%0A%20%20%7D%0A%7D%0A%0Avar%20animal%20%3D%20%7B%20flags%3A%20AnimalFlags.None%20%7D%3B%0AprintAnimalAbilities(animal)%3B%20%2F%2F%20nothing%0Aanimal.flags%20%7C%3D%20AnimalFlags.HasClaws%3B%0AprintAnimalAbilities(animal)%3B%20%2F%2F%20animal%20has%20claws%0Aanimal.flags%20%26%3D%20~AnimalFlags.HasClaws%3B%0AprintAnimalAbilities(animal)%3B%20%2F%2F%20nothing%0Aanimal.flags%20%7C%3D%20AnimalFlags.HasClaws%20%7C%20AnimalFlags.CanFly%3B%0AprintAnimalAbilities(animal)%3B%20%2F%2F%20animal%20has%20claws%2C%20animal%20can%20fly%0A%0A%60%60%60%0A%0A%23%23%23%23%20%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%9E%9A%E4%B8%BE%0A%60%60%60js%0Aexport%20enum%20EvidenceTypeEnum%20%7B%0A%20%20UNKNOWN%20%3D%20''%2C%0A%20%20PASSPORT_VISA%20%3D%20'passport_visa'%2C%0A%20%20PASSPORT%20%3D%20'passport'%2C%0A%20%20SIGHTED_STUDENT_CARD%20%3D%20'sighted_tertiary_edu_id'%2C%0A%20%20SIGHTED_KEYPASS_CARD%20%3D%20'sighted_keypass_card'%2C%0A%20%20SIGHTED_PROOF_OF_AGE_CARD%20%3D%20'sighted_proof_of_age_card'%0A%7D%0A%0A%2F%2F%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E5%AE%83%E4%BB%AC%E7%94%A8%E4%BA%8E%E7%AE%80%E5%8D%95%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%AF%94%E8%BE%83%EF%BC%9A%0A%2F%2F%20Where%20%60someStringFromBackend%60%20will%20be%20''%20%7C%20'passport_visa'%20%7C%20'passport'%20...%20etc.%0Aconst%20value%20%3D%20someStringFromBackend%20as%20EvidenceTypeEnum%3B%0A%0A%2F%2F%20Sample%20use%20in%20code%0Aif%20(value%20%3D%3D%3D%20EvidenceTypeEnum.PASSPORT)%20%7B%0A%20%20console.log('You%20provided%20a%20passport')%3B%0A%20%20console.log(value)%3B%20%2F%2F%20%60passport%60%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E5%B8%B8%E9%87%8F%E6%9E%9A%E4%B8%BE%0A%60%60%60js%0Aconst%20enum%20Tristate%20%7B%0A%20%20False%2C%0A%20%20True%2C%0A%20%20Unknown%0A%7D%0A%0Aconst%20lie%20%3D%20Tristate.False%3B%0A%0A%2F%2F%E7%BC%96%E8%AF%91%E5%90%8E%0Alet%20lie%20%3D%200%3B%0A%60%60%60%0A%0A%23%23%23%23%23%20%E5%B8%B8%E9%87%8F%E6%9E%9A%E4%B8%BE%20preserveConstEnums%20%E9%80%89%E9%A1%B9%0A*%E4%BD%BF%E7%94%A8%E5%86%85%E8%81%94%E8%AF%AD%E6%B3%95%E5%AF%B9%E6%80%A7%E8%83%BD%E6%9C%89%E6%98%8E%E6%98%BE%E7%9A%84%E6%8F%90%E5%8D%87%E4%BD%9C%E7%94%A8%E3%80%82%E8%BF%90%E8%A1%8C%E6%97%B6%E6%B2%A1%E6%9C%89%20Tristate%20%E5%8F%98%E9%87%8F%E7%9A%84%E4%BA%8B%E5%AE%9E%EF%BC%8C%E6%98%AF%E5%9B%A0%E4%B8%BA%E7%BC%96%E8%AF%91%E5%99%A8%E5%B8%AE%E5%8A%A9%E4%BD%A0%E6%8A%8A%E4%B8%80%E4%BA%9B%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E6%B2%A1%E6%9C%89%E7%94%A8%E5%88%B0%E7%9A%84%E4%B8%8D%E7%BC%96%E8%AF%91%E6%88%90%20JavaScript%E3%80%82%E7%84%B6%E8%80%8C%EF%BC%8C%E4%BD%A0%E5%8F%AF%E8%83%BD%E6%83%B3%E8%AE%A9%E7%BC%96%E8%AF%91%E5%99%A8%E4%BB%8D%E7%84%B6%E6%8A%8A%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B%E7%BC%96%E8%AF%91%E6%88%90%20JavaScript%EF%BC%8C%E7%94%A8%E4%BA%8E%E5%A6%82%E4%B8%8A%E4%BE%8B%E5%AD%90%E4%B8%AD%E4%BB%8E%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%88%B0%E6%95%B0%E5%AD%97%EF%BC%8C%E6%88%96%E8%80%85%E6%98%AF%E4%BB%8E%E6%95%B0%E5%AD%97%E5%88%B0%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%9F%A5%E6%89%BE%E3%80%82%E5%9C%A8%E8%BF%99%E7%A7%8D%E6%83%85%E6%99%AF%E4%B8%8B%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E7%BC%96%E8%AF%91%E9%80%89%E9%A1%B9%20--preserveConstEnums%EF%BC%8C%E5%AE%83%E4%BC%9A%E7%BC%96%E8%AF%91%E5%87%BA%20var%20Tristate%20%E7%9A%84%E5%AE%9A%E4%B9%89%EF%BC%8C%E5%9B%A0%E6%AD%A4%E4%BD%A0%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%EF%BC%8C%E6%89%8B%E5%8A%A8%E4%BD%BF%E7%94%A8%20Tristate%5B'False'%5D%20%E5%92%8C%20Tristate%5B0%5D%E3%80%82%E5%B9%B6%E4%B8%94%E8%BF%99%E4%B8%8D%E4%BC%9A%E4%BB%A5%E4%BB%BB%E4%BD%95%E6%96%B9%E5%BC%8F%E5%BD%B1%E5%93%8D%E5%86%85%E8%81%94%E3%80%82*%0A%0A%23%23%23%23%20%E6%9C%89%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95%E7%9A%84%E6%9E%9A%E4%B8%BE%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%20enum%20%2B%20namespace%20%E7%9A%84%E5%A3%B0%E6%98%8E%E7%9A%84%E6%96%B9%E5%BC%8F%E5%90%91%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B%E6%B7%BB%E5%8A%A0%E9%9D%99%E6%80%81%E6%96%B9%E6%B3%95%E3%80%82%E5%A6%82%E4%B8%8B%E4%BE%8B%E6%89%80%E7%A4%BA%EF%BC%8C%E6%88%91%E4%BB%AC%E5%B0%86%E9%9D%99%E6%80%81%E6%88%90%E5%91%98%20isBusinessDay%20%E6%B7%BB%E5%8A%A0%E5%88%B0%E6%9E%9A%E4%B8%BE%E4%B8%8A%EF%BC%9A%0A%60%60%60js%0Aenum%20Weekday%20%7B%0A%20%20Monday%2C%0A%20%20Tuesday%2C%0A%20%20Wednesday%2C%0A%20%20Thursday%2C%0A%20%20Friday%2C%0A%20%20Saturday%2C%0A%20%20Sunday%0A%7D%0A%0Anamespace%20Weekday%20%7B%0A%20%20export%20function%20isBusinessDay(day%3A%20Weekday)%20%7B%0A%20%20%20%20switch%20(day)%20%7B%0A%20%20%20%20%20%20case%20Weekday.Saturday%3A%0A%20%20%20%20%20%20case%20Weekday.Sunday%3A%0A%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%20%20default%3A%0A%20%20%20%20%20%20%20%20return%20true%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A%0Aconst%20mon%20%3D%20Weekday.Monday%3B%0Aconst%20sun%20%3D%20Weekday.Sunday%3B%0A%0Aconsole.log(Weekday.isBusinessDay(mon))%3B%20%2F%2F%20true%0Aconsole.log(Weekday.isBusinessDay(sun))%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E5%BC%80%E6%94%BE%E5%BC%8F%E6%9E%9A%E4%B8%BE%0A%0A*%E4%BD%A0%E5%8F%AA%E6%9C%89%E5%9C%A8%E4%B8%8D%E4%BD%BF%E7%94%A8%E6%A8%A1%E5%9D%97%E6%97%B6%EF%BC%8C%E5%BC%80%E6%94%BE%E5%BC%8F%E7%9A%84%E6%9E%9A%E4%B8%BE%E6%89%8D%E6%9C%89%E6%84%8F%E4%B9%89%EF%BC%8C%E4%BD%A0%E5%BA%94%E8%AF%A5%E4%BD%BF%E7%94%A8%E6%A8%A1%E5%9D%97%EF%BC%8C%E5%9B%A0%E6%AD%A4%E8%BF%99%E9%83%A8%E5%88%86%E5%9C%A8%E6%96%87%E7%AB%A0%E6%9C%80%E5%90%8E%E3%80%82*%0A%0A%0A%60%60%60js%0A%2F%2F%E4%BD%A0%E5%8F%AF%E4%BB%A5%E8%B7%A8%E5%A4%9A%E4%B8%AA%E6%96%87%E4%BB%B6%E6%8B%86%E5%88%86%EF%BC%88%E5%92%8C%E6%89%A9%E5%B1%95%EF%BC%89%E6%9E%9A%E4%B8%BE%E5%AE%9A%E4%B9%89%EF%BC%8C%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E6%8A%8A%20Color%20%E7%9A%84%E5%AE%9A%E4%B9%89%E6%8B%86%E5%88%86%E8%87%B3%E4%B8%A4%E4%B8%AA%E5%9D%97%E4%B8%AD%EF%BC%9A%0Aenum%20Color%20%7B%0A%20%20Red%2C%0A%20%20Green%2C%0A%20%20Blue%0A%7D%0A%0Aenum%20Color%20%7B%0A%20%20DarkRed%20%3D%203%2C%0A%20%20DarkGreen%2C%0A%20%20DarkBlue%0A%7D%0A%60%60%60%0A*%E4%BD%A0%E5%BA%94%E8%AF%A5%E5%9C%A8%E6%9E%9A%E4%B8%BE%E7%9A%84%E5%BB%B6%E7%BB%AD%E5%9D%97%E4%B8%AD%EF%BC%8C%E5%88%9D%E5%A7%8B%E5%8C%96%E7%AC%AC%E4%B8%80%E4%B8%AA%E6%88%90%E5%91%98%EF%BC%8C%E4%BB%A5%E4%BE%BF%E7%94%9F%E6%88%90%E7%9A%84%E4%BB%A3%E7%A0%81%E4%B8%8D%E6%98%AF%E5%85%88%E5%89%8D%E5%AE%9A%E4%B9%89%E7%9A%84%E6%9E%9A%E4%B8%BE%E7%B1%BB%E5%9E%8B%E5%80%BC%E3%80%82TypeScript%20%E5%B0%86%E4%BC%9A%E5%8F%91%E5%87%BA%E8%AD%A6%E5%91%8A%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E5%AE%9A%E4%B9%89%E5%88%9D%E5%A7%8B%E5%80%BC%EF%BC%88%E9%94%99%E8%AF%AF%E4%BF%A1%E6%81%AF%EF%BC%9AIn%20an%20enum%20with%20multiple%20declarations%2C%20only%20one%20declaration%20can%20omit%20an%20initializer%20for%20its%20first%20enum%20element.%EF%BC%89%E3%80%82*%0A%0A%23%23%20lib.d.ts%0A%E5%BD%93%E4%BD%A0%E5%AE%89%E8%A3%85%20TypeScript%20%E6%97%B6%EF%BC%8C%E4%BC%9A%E9%A1%BA%E5%B8%A6%E5%AE%89%E8%A3%85%E4%B8%80%E4%B8%AA%20lib.d.ts%20%E5%A3%B0%E6%98%8E%E6%96%87%E4%BB%B6%E3%80%82%E8%BF%99%E4%B8%AA%E6%96%87%E4%BB%B6%E5%8C%85%E5%90%AB%20JavaScript%20%E8%BF%90%E8%A1%8C%E6%97%B6%E4%BB%A5%E5%8F%8A%20DOM%20%E4%B8%AD%E5%AD%98%E5%9C%A8%E5%90%84%E7%A7%8D%E5%B8%B8%E8%A7%81%E7%9A%84%E7%8E%AF%E5%A2%83%E5%A3%B0%E6%98%8E%E3%80%82%0A1.%E5%AE%83%E8%87%AA%E5%8A%A8%E5%8C%85%E5%90%AB%E5%9C%A8%20TypeScript%20%E9%A1%B9%E7%9B%AE%E7%9A%84%E7%BC%96%E8%AF%91%E4%B8%8A%E4%B8%8B%E6%96%87%E4%B8%AD%EF%BC%9B%0A2.%E5%AE%83%E8%83%BD%E8%AE%A9%E4%BD%A0%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B%E4%B9%A6%E5%86%99%E7%BB%8F%E8%BF%87%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%9F%A5%E7%9A%84%20JavaScript%20%E4%BB%A3%E7%A0%81%E3%80%82%0A%0A*%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E6%8C%87%E5%AE%9A%20--noLib%20%E7%9A%84%E7%BC%96%E8%AF%91%E5%99%A8%E5%91%BD%E4%BB%A4%E8%A1%8C%E6%A0%87%E5%BF%97%EF%BC%88%E6%88%96%E8%80%85%E5%9C%A8%20tsconfig.json%20%E4%B8%AD%E6%8C%87%E5%AE%9A%E9%80%89%E9%A1%B9%20noLib%3A%20true%EF%BC%89%E4%BB%8E%E4%B8%8A%E4%B8%8B%E6%96%87%E4%B8%AD%E6%8E%92%E9%99%A4%E6%AD%A4%E6%96%87%E4%BB%B6%E3%80%82*%0A%0A%23%23%23%23%20%E4%BD%BF%E7%94%A8%E4%BE%8B%E5%AD%90%0A%60%60%60js%0Aconst%20foo%20%3D%20123%3B%0Aconst%20bar%20%3D%20foo.toString()%3B%2F%2F%E8%BF%99%E6%AE%B5%E4%BB%A3%E7%A0%81%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%9F%A5%E6%AD%A3%E5%B8%B8%EF%BC%8C%E5%9B%A0%E4%B8%BA%20lib.d.ts%20%E4%B8%BA%E6%89%80%E6%9C%89%20JavaScript%20%E5%AF%B9%E8%B1%A1%E5%AE%9A%E4%B9%89%E4%BA%86%20toString%20%E6%96%B9%E6%B3%95%0A%0A%2F%2F%E5%9C%A8%20noLib%20%E9%80%89%E9%A1%B9%E4%B8%8B%0Aconst%20foo%20%3D%20123%3B%0Aconst%20bar%20%3D%20foo.toString()%3B%20%2F%2F%20Error%3A%20%E5%B1%9E%E6%80%A7%20toString%20%E4%B8%8D%E5%AD%98%E5%9C%A8%E7%B1%BB%E5%9E%8B%20number%20%E4%B8%8A%0A%60%60%60%0A%0A%23%23%23%23%20%E8%A7%82%E5%AF%9F%20lib.d.ts%20%E7%9A%84%E5%86%85%E5%AE%B9%0Alib.d.ts%20%E7%9A%84%E5%86%85%E5%AE%B9%E4%B8%BB%E8%A6%81%E6%98%AF%E4%B8%80%E4%BA%9B%E5%8F%98%E9%87%8F%E5%A3%B0%E6%98%8E%EF%BC%88%E5%A6%82%EF%BC%9Awindow%E3%80%81document%E3%80%81math%EF%BC%89%E5%92%8C%E4%B8%80%E4%BA%9B%E7%B1%BB%E4%BC%BC%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%A3%B0%E6%98%8E%EF%BC%88%E5%A6%82%EF%BC%9AWindow%E3%80%81Document%E3%80%81Math%EF%BC%89%E3%80%82%0A%0A%E8%AE%A9%E6%88%91%E4%BB%AC%E6%9D%A5%E7%9C%8B%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E5%A3%B0%E6%98%8E%E7%9A%84%E7%A4%BA%E4%BE%8B%EF%BC%8C%E5%A6%82%20window%20%E8%A2%AB%E5%AE%9A%E4%B9%89%E4%B8%BA%EF%BC%9A%0A%60%60%60js%0Adeclare%20var%20window%3A%20Window%3B%0A%60%60%60%0A%E8%BF%99%E5%8F%AA%E6%98%AF%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%20declare%20var%EF%BC%8C%E5%90%8E%E9%9D%A2%E8%B7%9F%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E5%90%8D%E7%A7%B0%EF%BC%88window%EF%BC%89%E5%92%8C%E4%B8%80%E4%B8%AA%E7%94%A8%E6%9D%A5%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%88Window%EF%BC%89%EF%BC%8C%E8%BF%99%E4%BA%9B%E5%8F%98%E9%87%8F%E9%80%9A%E5%B8%B8%E6%8C%87%E5%90%91%E4%B8%80%E4%BA%9B%E5%85%A8%E5%B1%80%E7%9A%84%E6%8E%A5%E5%8F%A3%EF%BC%8C%E4%BE%8B%E5%A6%82%EF%BC%8C%E4%BB%A5%E4%B8%8B%E6%98%AF%20Window%20%E6%8E%A5%E5%8F%A3%E7%9A%84%E4%B8%80%E5%B0%8F%E9%83%A8%E5%88%86%EF%BC%9A%0A%60%60%60js%0Ainterface%20Window%0A%20%20extends%20EventTarget%2C%0A%20%20%20%20WindowTimers%2C%0A%20%20%20%20WindowSessionStorage%2C%0A%20%20%20%20WindowLocalStorage%2C%0A%20%20%20%20WindowConsole%2C%0A%20%20%20%20GlobalEventHandlers%2C%0A%20%20%20%20IDBEnvironment%2C%0A%20%20%20%20WindowBase64%20%7B%0A%20%20animationStartTime%3A%20number%3B%0A%20%20applicationCache%3A%20ApplicationCache%3B%0A%20%20clientInformation%3A%20Navigator%3B%0A%20%20closed%3A%20boolean%3B%0A%20%20crypto%3A%20Crypto%3B%0A%20%20%2F%2F%20so%20on%20and%20so%20forth...%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E4%BF%AE%E6%94%B9%E5%8E%9F%E5%A7%8B%E7%B1%BB%E5%9E%8B%0A%E5%9C%A8%20TypeScript%20%E4%B8%AD%EF%BC%8C%E6%8E%A5%E5%8F%A3%E6%98%AF%E5%BC%80%E6%94%BE%E5%BC%8F%E7%9A%84%EF%BC%8C%E8%BF%99%E6%84%8F%E5%91%B3%E7%9D%80%E5%BD%93%E4%BD%A0%E6%83%B3%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%AD%98%E5%9C%A8%E7%9A%84%E6%88%90%E5%91%98%E6%97%B6%EF%BC%8C%E5%8F%AA%E9%9C%80%E8%A6%81%E5%B0%86%E5%AE%83%E4%BB%AC%E6%B7%BB%E5%8A%A0%E8%87%B3%20lib.d.ts%20%E4%B8%AD%E7%9A%84%E6%8E%A5%E5%8F%A3%E5%A3%B0%E6%98%8E%E4%B8%AD%E5%8D%B3%E5%8F%AF%EF%BC%8CTypeScript%20%E5%B0%86%E4%BC%9A%E8%87%AA%E5%8A%A8%E6%8E%A5%E6%94%B6%E5%AE%83%E3%80%82%E6%B3%A8%E6%84%8F%EF%BC%8C%E4%BD%A0%E9%9C%80%E8%A6%81%E5%9C%A8%E5%85%A8%E5%B1%80%E6%A8%A1%E5%9D%97%E4%B8%AD%E5%81%9A%E8%BF%99%E4%BA%9B%E4%BF%AE%E6%94%B9%EF%BC%8C%E4%BB%A5%E4%BD%BF%E8%BF%99%E4%BA%9B%E6%8E%A5%E5%8F%A3%E4%B8%8E%20lib.d.ts%20%E7%9B%B8%E5%85%B3%E8%81%94%E3%80%82%E6%88%91%E4%BB%AC%E6%8E%A8%E8%8D%90%E4%BD%A0%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E7%A7%B0%E4%B8%BA%20global.d.ts%20%E7%9A%84%E7%89%B9%E6%AE%8A%E6%96%87%E4%BB%B6%E3%80%82%0A%0A%0A%E8%BF%99%E9%87%8C%E6%9C%89%E6%88%91%E4%BB%AC%E9%9C%80%E8%A6%81%E6%B7%BB%E5%8A%A0%E8%87%B3%20Window%EF%BC%8CMath%EF%BC%8CDate%20%E7%9A%84%E4%B8%80%E4%BA%9B%E4%BE%8B%E5%AD%90%EF%BC%9A%0A%0AWindow%EF%BC%9A%0A%60%60%60js%0Ainterface%20Window%20%7B%0A%20%20helloWorld()%3A%20void%3B%0A%7D%0A%0A%2F%2F%20Add%20it%20at%20runtime%0Awindow.helloWorld%20%3D%20()%20%3D%3E%20console.log('hello%20world')%3B%0A%0A%2F%2F%20Call%20it%0Awindow.helloWorld()%3B%0A%0A%2F%2F%20%E6%BB%A5%E7%94%A8%E4%BC%9A%E5%AF%BC%E8%87%B4%E9%94%99%E8%AF%AF%0Awindow.helloWorld('gracius')%3B%20%2F%2F%20Error%3A%20%E6%8F%90%E4%BE%9B%E7%9A%84%E5%8F%82%E6%95%B0%E4%B8%8E%E7%9B%AE%E6%A0%87%E4%B8%8D%E5%8C%B9%E9%85%8D%0A%60%60%60%0A%0A%23%23%23%23%20%E4%BD%BF%E7%94%A8%E4%BD%A0%E8%87%AA%E5%B7%B1%E5%AE%9A%E4%B9%89%E7%9A%84%20lib.d.ts%0A%E6%AD%A3%E5%A6%82%E4%B8%8A%E6%96%87%E6%89%80%E8%AF%B4%EF%BC%8C%E4%BD%BF%E7%94%A8%20--noLib%20%E7%BC%96%E8%AF%91%E9%80%89%E9%A1%B9%E4%BC%9A%E5%AF%BC%E8%87%B4%20TypeScript%20%E6%8E%92%E9%99%A4%E8%87%AA%E5%8A%A8%E5%8C%85%E5%90%AB%E7%9A%84%20lib.d.ts%20%E6%96%87%E4%BB%B6%E3%80%82%E4%B8%BA%E4%BB%80%E4%B9%88%E8%BF%99%E4%B8%AA%E5%8A%9F%E8%83%BD%E6%98%AF%E6%9C%89%E6%95%88%E7%9A%84%EF%BC%8C%E6%88%91%E4%BE%8B%E4%B8%BE%E4%BA%86%E4%B8%80%E4%BA%9B%E5%B8%B8%E8%A7%81%E5%8E%9F%E5%9B%A0%EF%BC%9A%0A%0A1.%E8%BF%90%E8%A1%8C%E7%9A%84%20JavaScript%20%E7%8E%AF%E5%A2%83%E4%B8%8E%E5%9F%BA%E4%BA%8E%E6%A0%87%E5%87%86%E6%B5%8F%E8%A7%88%E5%99%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E7%8E%AF%E5%A2%83%E6%9C%89%E5%BE%88%E5%A4%A7%E4%B8%8D%E5%90%8C%EF%BC%9B%0A2.%E4%BD%A0%E5%B8%8C%E6%9C%9B%E5%9C%A8%E4%BB%A3%E7%A0%81%E9%87%8C%E4%B8%A5%E6%A0%BC%E7%9A%84%E6%8E%A7%E5%88%B6%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%EF%BC%8C%E4%BE%8B%E5%A6%82%EF%BC%9Alib.d.ts%20%E5%B0%86%20item%20%E5%AE%9A%E4%B9%89%E4%B8%BA%E5%85%A8%E5%B1%80%E5%8F%98%E9%87%8F%EF%BC%8C%E4%BD%A0%E4%B8%8D%E5%B8%8C%E6%9C%9B%E5%AE%83%E6%B3%84%E6%BC%8F%E5%88%B0%E4%BD%A0%E7%9A%84%E4%BB%A3%E7%A0%81%E9%87%8C%0A%0A%E4%B8%80%E6%97%A6%E4%BD%A0%E6%8E%92%E9%99%A4%E4%BA%86%E9%BB%98%E8%AE%A4%E7%9A%84%20lib.d.ts%20%E6%96%87%E4%BB%B6%EF%BC%8C%E4%BD%A0%E5%B0%B1%E5%8F%AF%E4%BB%A5%E5%9C%A8%E7%BC%96%E8%AF%91%E4%B8%8A%E4%B8%8B%E6%96%87%E4%B8%AD%E5%8C%85%E5%90%AB%E4%B8%80%E4%B8%AA%E5%91%BD%E5%90%8D%E7%9B%B8%E4%BC%BC%E7%9A%84%E6%96%87%E4%BB%B6%EF%BC%8CTypeScript%20%E5%B0%86%E6%8F%90%E5%8F%96%E8%AF%A5%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%9F%A5%E3%80%82%0A%0A*%E5%B0%8F%E5%BF%83%E4%BD%BF%E7%94%A8%20--noLib%20%E9%80%89%E9%A1%B9%EF%BC%8C%E4%B8%80%E6%97%A6%E4%BD%A0%E4%BD%BF%E7%94%A8%E4%BA%86%E5%AE%83%EF%BC%8C%E5%BD%93%E4%BD%A0%E6%8A%8A%E4%BD%A0%E7%9A%84%E9%A1%B9%E7%9B%AE%E5%88%86%E4%BA%AB%E7%BB%99%E5%85%B6%E4%BB%96%E4%BA%BA%E6%97%B6%EF%BC%8C%E5%AE%83%E4%BB%AC%E4%B9%9F%E5%B0%86%E8%A2%AB%E8%BF%AB%E4%BD%BF%E7%94%A8%20--noLib%20%E9%80%89%E9%A1%B9%EF%BC%8C%E6%9B%B4%E7%B3%9F%E7%B3%95%E7%9A%84%E6%98%AF%EF%BC%8C%E5%A6%82%E6%9E%9C%E5%B0%86%E8%BF%99%E4%BA%9B%E4%BB%A3%E7%A0%81%E6%94%BE%E5%85%A5%E4%BD%A0%E7%9A%84%E9%A1%B9%E7%9B%AE%E4%B8%AD%EF%BC%8C%E4%BD%A0%E5%8F%AF%E8%83%BD%E9%9C%80%E8%A6%81%E5%B0%86%E5%AE%83%E4%BB%AC%E7%A7%BB%E6%A4%8D%E5%88%B0%E5%9F%BA%E4%BA%8E%E4%BD%A0%E7%9A%84%E4%BB%A3%E7%A0%81%E7%9A%84%20lib%20%E4%B8%AD%E3%80%82*%0A%0A%23%23%23%23%20%E7%BC%96%E8%AF%91%E7%9B%AE%E6%A0%87%E5%AF%B9%20lib.d.ts%20%E7%9A%84%E5%BD%B1%E5%93%8D%0A%E8%AE%BE%E7%BD%AE%E7%BC%96%E8%AF%91%E7%9B%AE%E6%A0%87%E4%B8%BA%20es6%20%E6%97%B6%EF%BC%8C%E8%83%BD%E5%AF%BC%E8%87%B4%20lib.d.ts%20%E5%8C%85%E5%90%AB%E6%9B%B4%E5%A4%9A%E5%83%8F%20Promise%20%E7%8E%B0%E4%BB%A3%EF%BC%88es6%EF%BC%89%E5%86%85%E5%AE%B9%E7%9A%84%E7%8E%AF%E5%A2%83%E5%A3%B0%E6%98%8E%E3%80%82%E7%BC%96%E8%AF%91%E5%99%A8%E7%9B%AE%E6%A0%87%E7%9A%84%E8%BF%99%E7%A7%8D%E4%BD%9C%E7%94%A8%EF%BC%8C%E6%94%B9%E5%8F%98%E4%BA%86%E4%BB%A3%E7%A0%81%E7%9A%84%E7%8E%AF%E5%A2%83%EF%BC%8C%E8%BF%99%E5%AF%B9%E6%9F%90%E4%BA%9B%E4%BA%BA%E6%9D%A5%E8%AF%B4%E6%98%AF%E7%90%86%E6%83%B3%E7%9A%84%EF%BC%8C%E4%BD%86%E6%98%AF%E8%BF%99%E5%AF%B9%E5%8F%A6%E5%A4%96%E4%B8%80%E4%BA%9B%E4%BA%BA%E6%9D%A5%E8%AF%B4%E9%80%A0%E6%88%90%E4%BA%86%E5%9B%B0%E6%89%B0%EF%BC%8C%E5%9B%A0%E4%B8%BA%E5%AE%83%E5%B0%86%E7%BC%96%E8%AF%91%E5%87%BA%E7%9A%84%E4%BB%A3%E7%A0%81%E4%B8%8E%E7%8E%AF%E5%A2%83%E6%B7%B7%E4%B8%BA%E4%B8%80%E8%B0%88%E3%80%82%0A%0A%E5%BD%93%E4%BD%A0%E6%83%B3%E5%AF%B9%E7%8E%AF%E5%A2%83%E8%BF%9B%E8%A1%8C%E6%9B%B4%E7%BB%86%E7%B2%92%E7%9A%84%E6%8E%A7%E5%88%B6%E6%97%B6%EF%BC%8C%E4%BD%A0%E5%BA%94%E8%AF%A5%E4%BD%BF%E7%94%A8%E6%88%91%E4%BB%AC%E6%8E%A5%E4%B8%8B%E6%9D%A5%E5%B0%86%E8%A6%81%E8%AE%A8%E8%AE%BA%E7%9A%84%20--lib%20%E9%80%89%E9%A1%B9%E3%80%82%0A%0A%E6%9C%89%E6%97%B6%EF%BC%8C%E4%BD%A0%E6%83%B3%E8%A6%81%E8%A7%A3%E8%80%A6%E7%BC%96%E8%AF%91%E7%9B%AE%E6%A0%87%EF%BC%88%E5%8D%B3%E7%94%9F%E6%88%90%E7%9A%84%20JavaScript%20%E7%89%88%E6%9C%AC%EF%BC%89%E5%92%8C%E7%8E%AF%E5%A2%83%E5%BA%93%E6%94%AF%E6%8C%81%E4%B9%8B%E9%97%B4%E7%9A%84%E5%85%B3%E7%B3%BB%E3%80%82%E4%BE%8B%E5%A6%82%E5%AF%B9%E4%BA%8E%20Promise%EF%BC%8C%E4%BD%A0%E7%9A%84%E7%BC%96%E8%AF%91%E7%9B%AE%E6%A0%87%E6%98%AF%20--target%20es5%EF%BC%8C%E4%BD%86%E6%98%AF%E4%BD%A0%E4%BB%8D%E7%84%B6%E6%83%B3%E4%BD%BF%E7%94%A8%E5%AE%83%EF%BC%8C%E8%BF%99%E6%97%B6%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%20lib%20%E5%AF%B9%E5%AE%83%E8%BF%9B%E8%A1%8C%E6%8E%A7%E5%88%B6%E3%80%82%0A%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E5%91%BD%E4%BB%A4%E8%A1%8C%E6%88%96%E8%80%85%E5%9C%A8%20tsconfig.json%20%E4%B8%AD%E6%8F%90%E4%BE%9B%E6%AD%A4%E9%80%89%E9%A1%B9%EF%BC%88%E6%8E%A8%E8%8D%90%EF%BC%89%EF%BC%9A%0A%0A%E5%91%BD%E4%BB%A4%E8%A1%8C%3A%0A%60%60%60%0Atsc%20--target%20es5%20--lib%20dom%2Ces6%0A%60%60%60%0A%0Aconfig.json%0A%60%60%60%0A%22compilerOptions%22%3A%20%7B%0A%20%20%20%20%22lib%22%3A%20%5B%22dom%22%2C%20%22es6%22%5D%0A%7D%0A%60%60%60%0A%0Alib%20%E5%88%86%E7%B1%BB%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%0AJavaScript%20%E5%8A%9F%E8%83%BD%0Aes5%0Aes6%0Aes2015%0Aes7%0Aes2016%0Aes2017%0Aesnext%0A%E8%BF%90%E8%A1%8C%E7%8E%AF%E5%A2%83%0Adom%0Adom.iterable%0Awebworker%0Ascripthost%0AESNext%20%E5%8A%9F%E8%83%BD%E9%80%89%E9%A1%B9%0Aes2015.core%0Aes2015.collection%0Aes2015.generator%0Aes2015.iterable%0Aes2015.promise%0Aes2015.proxy%0Aes2015.reflect%0Aes2015.symbol%0Aes2015.symbol.wellknown%0Aes2016.array.include%0Aes2017.object%0Aes2017.sharedmemory%0Aesnext.asynciterable%0A%0A%0A*--lib%20%E9%80%89%E9%A1%B9%E6%8F%90%E4%BE%9B%E9%9D%9E%E5%B8%B8%E7%B2%BE%E7%BB%86%E7%9A%84%E6%8E%A7%E5%88%B6%EF%BC%8C%E5%9B%A0%E6%AD%A4%E4%BD%A0%E6%9C%80%E6%9C%89%E5%8F%AF%E8%83%BD%E4%BB%8E%E8%BF%90%E8%A1%8C%E7%8E%AF%E5%A2%83%E4%B8%8E%20JavaScript%20%E5%8A%9F%E8%83%BD%E7%B1%BB%E5%88%AB%E4%B8%AD%E5%88%86%E5%88%AB%E9%80%89%E6%8B%A9%E4%B8%80%E9%A1%B9%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%B2%A1%E6%9C%89%E6%8C%87%E5%AE%9A%20--lib%EF%BC%8C%E5%88%99%E4%BC%9A%E5%AF%BC%E5%85%A5%E9%BB%98%E8%AE%A4%E5%BA%93%EF%BC%9A%0A%0A*--target%20%E9%80%89%E9%A1%B9%E4%B8%BA%20es5%20%E6%97%B6%EF%BC%8C%E4%BC%9A%E5%AF%BC%E5%85%A5%20es5%2C%20dom%2C%20scripthost%E3%80%82%0A--target%20%E9%80%89%E9%A1%B9%E4%B8%BA%20es6%20%E6%97%B6%EF%BC%8C%E4%BC%9A%E5%AF%BC%E5%85%A5%20es6%2C%20dom%2C%20dom.iterable%2C%20scripthost%E3%80%82**%0A%0A%23%23%23%23%20%E5%9C%A8%E6%97%A7%E7%9A%84%20JavaScript%20%E5%BC%95%E6%93%8E%E6%97%B6%E4%BD%BF%E7%94%A8%20Polyfill%0A%E8%A6%81%E4%BD%BF%E7%94%A8%E4%B8%80%E4%BA%9B%E6%96%B0%E5%8A%9F%E8%83%BD%E5%A6%82%20Map%E3%80%81Set%E3%80%81Promise%EF%BC%88%E9%9A%8F%E7%9D%80%E6%97%B6%E9%97%B4%E6%8E%A8%E7%A7%BB%E4%BC%9A%E5%8F%98%E5%8C%96%EF%BC%89%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E7%8E%B0%E4%BB%A3%E7%9A%84%20lib%20%E9%80%89%E9%A1%B9%EF%BC%8C%E5%B9%B6%E4%B8%94%E9%9C%80%E8%A6%81%E5%AE%89%E8%A3%85%20core-js%EF%BC%9A%0A%60%60%60%0Anpm%20install%20core-js%20--save-dev%0A%60%60%60%0A%E6%8E%A5%E7%9D%80%EF%BC%8C%E5%9C%A8%E4%BD%A0%E7%9A%84%E9%A1%B9%E7%9B%AE%E9%87%8C%E5%AF%BC%E5%85%A5%E5%AE%83%EF%BC%9A%0A%60%60%60%0Aimport%20'core-js'%3B%0A%60%60%60%0A%0A%23%23%20%E5%87%BD%E6%95%B0%0A%0A%23%23%23%23%20%E5%8F%82%E6%95%B0%E6%B3%A8%E8%A7%A3%0A%60%60%60js%0A%2F%2F%20variable%20annotation%0Alet%20sampleVariable%3A%20%7B%20bar%3A%20number%20%7D%3B%0A%0A%2F%2F%20function%20parameter%20annotation%0Afunction%20foo(sampleParameter%3A%20%7B%20bar%3A%20number%20%7D)%20%7B%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E8%BF%94%E5%9B%9E%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%0A%60%60%60js%0Ainterface%20Foo%20%7B%0A%20%20foo%3A%20string%3B%0A%7D%0A%0A%2F%2F%20Return%20type%20annotated%20as%20%60%3A%20Foo%60%0Afunction%20foo(sample%3A%20Foo)%3A%20Foo%20%7B%0A%20%20return%20sample%3B%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E5%8F%AF%E9%80%89%E5%8F%82%E6%95%B0%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E5%B0%86%E5%8F%82%E6%95%B0%E6%A0%87%E8%AE%B0%E4%B8%BA%E5%8F%AF%E9%80%89%3A%0A%60%60%60js%0Afunction%20foo(bar%3A%20number%2C%20bas%3F%3A%20string)%3A%20void%20%7B%0A%20%20%2F%2F%20..%0A%7D%0A%0Afoo(123)%3B%0Afoo(123%2C%20'hello')%3B%0A%60%60%60%0A%0A%E6%88%96%E8%80%85%EF%BC%8C%E5%BD%93%E8%B0%83%E7%94%A8%E8%80%85%E6%B2%A1%E6%9C%89%E6%8F%90%E4%BE%9B%E8%AF%A5%E5%8F%82%E6%95%B0%E6%97%B6%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E6%8F%90%E4%BE%9B%E4%B8%80%E4%B8%AA%E9%BB%98%E8%AE%A4%E5%80%BC%EF%BC%88%E5%9C%A8%E5%8F%82%E6%95%B0%E5%A3%B0%E6%98%8E%E5%90%8E%E4%BD%BF%E7%94%A8%20%3D%20someValue%20%EF%BC%89%EF%BC%9A%0A%60%60%60js%0Afunction%20foo(bar%3A%20number%2C%20bas%3A%20string%20%3D%20'hello')%20%7B%0A%20%20console.log(bar%2C%20bas)%3B%0A%7D%0A%0Afoo(123)%3B%20%2F%2F%20123%2C%20hello%0Afoo(123%2C%20'world')%3B%20%2F%2F%20123%2C%20world%0A%60%60%60%0A%0A%23%23%23%23%20%E9%87%8D%E8%BD%BD%0A%0A%60%60%60js%0A%2F%2F%20%E9%87%8D%E8%BD%BD%0Afunction%20padding(all%3A%20number)%3B%0Afunction%20padding(topAndBottom%3A%20number%2C%20leftAndRight%3A%20number)%3B%0Afunction%20padding(top%3A%20number%2C%20right%3A%20number%2C%20bottom%3A%20number%2C%20left%3A%20number)%3B%0A%2F%2F%20Actual%20implementation%20that%20is%20a%20true%20representation%20of%20all%20the%20cases%20the%20function%20body%20needs%20to%20handle%0Afunction%20padding(a%3A%20number%2C%20b%3F%3A%20number%2C%20c%3F%3A%20number%2C%20d%3F%3A%20number)%20%7B%0A%20%20if%20(b%20%3D%3D%3D%20undefined%20%26%26%20c%20%3D%3D%3D%20undefined%20%26%26%20d%20%3D%3D%3D%20undefined)%20%7B%0A%20%20%20%20b%20%3D%20c%20%3D%20d%20%3D%20a%3B%0A%20%20%7D%20else%20if%20(c%20%3D%3D%3D%20undefined%20%26%26%20d%20%3D%3D%3D%20undefined)%20%7B%0A%20%20%20%20c%20%3D%20a%3B%0A%20%20%20%20d%20%3D%20b%3B%0A%20%20%7D%0A%20%20return%20%7B%0A%20%20%20%20top%3A%20a%2C%0A%20%20%20%20right%3A%20b%2C%0A%20%20%20%20bottom%3A%20c%2C%0A%20%20%20%20left%3A%20d%0A%20%20%7D%3B%0A%7D%0A%0A%0Apadding(1)%3B%20%2F%2F%20Okay%3A%20all%0Apadding(1%2C%201)%3B%20%2F%2F%20Okay%3A%20topAndBottom%2C%20leftAndRight%0Apadding(1%2C%201%2C%201%2C%201)%3B%20%2F%2F%20Okay%3A%20top%2C%20right%2C%20bottom%2C%20left%0A%0Apadding(1%2C%201%2C%201)%3B%20%2F%2F%20Error%3A%20Not%20a%20part%20of%20the%20available%20overloads%0A%60%60%60%0A%0A%23%23%23%23%20%E5%87%BD%E6%95%B0%E5%A3%B0%E6%98%8E%0A%E5%9C%A8%E6%B2%A1%E6%9C%89%E6%8F%90%E4%BE%9B%E5%87%BD%E6%95%B0%E5%AE%9E%E7%8E%B0%E7%9A%84%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E6%9C%89%E4%B8%A4%E7%A7%8D%E5%A3%B0%E6%98%8E%E5%87%BD%E6%95%B0%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%96%B9%E5%BC%8F%3A%0A%60%60%60js%0Atype%20LongHand%20%3D%20%7B%0A%20%20(a%3A%20number)%3A%20number%3B%0A%7D%3B%0A%0Atype%20ShortHand%20%3D%20(a%3A%20number)%20%3D%3E%20number%3B%0A%60%60%60%0A%E4%BD%86%E6%98%AF%EF%BC%8C%E5%BD%93%E4%BD%A0%E6%83%B3%E4%BD%BF%E7%94%A8%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD%E6%97%B6%EF%BC%8C%E5%8F%AA%E8%83%BD%E7%94%A8%E7%AC%AC%E4%B8%80%E7%A7%8D%E6%96%B9%E5%BC%8F%3A%0A%60%60%60js%0Atype%20LongHandAllowsOverloadDeclarations%20%3D%20%7B%0A%20%20(a%3A%20number)%3A%20number%3B%0A%20%20(a%3A%20string)%3A%20string%3B%0A%7D%3B%0A%60%60%60%0A%0A%23%23%20%E5%8F%AF%E8%B0%83%E7%94%A8%E7%9A%84%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D%E6%88%96%E8%80%85%E6%8E%A5%E5%8F%A3%E6%9D%A5%E8%A1%A8%E7%A4%BA%E4%B8%80%E4%B8%AA%E5%8F%AF%E8%A2%AB%E8%B0%83%E7%94%A8%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%EF%BC%9A%0A%60%60%60js%0Ainterface%20ReturnString%20%7B%0A%20%20()%3A%20string%3B%0A%7D%0A%60%60%60%0A%E5%AE%83%E5%8F%AF%E4%BB%A5%E8%A1%A8%E7%A4%BA%E4%B8%80%E4%B8%AA%E8%BF%94%E5%9B%9E%E5%80%BC%E4%B8%BA%20string%20%E7%9A%84%E5%87%BD%E6%95%B0%EF%BC%9A%0A%60%60%60js%0Adeclare%20const%20foo%3A%20ReturnString%3B%0A%0Aconst%20bar%20%3D%20foo()%3B%20%2F%2F%20bar%20%E8%A2%AB%E6%8E%A8%E6%96%AD%E4%B8%BA%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E3%80%82%0A%60%60%60%0A%0A%23%23%23%23%20%E4%B8%80%E4%B8%AA%E5%AE%9E%E9%99%85%E7%9A%84%E4%BE%8B%E5%AD%90%0A%E5%BD%93%E7%84%B6%EF%BC%8C%E5%83%8F%E8%BF%99%E6%A0%B7%E4%B8%80%E4%B8%AA%E5%8F%AF%E8%A2%AB%E8%B0%83%E7%94%A8%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%EF%BC%8C%E4%BD%A0%E4%B9%9F%E5%8F%AF%E4%BB%A5%E6%A0%B9%E6%8D%AE%E5%AE%9E%E9%99%85%E6%9D%A5%E4%BC%A0%E9%80%92%E4%BB%BB%E4%BD%95%E5%8F%82%E6%95%B0%E3%80%81%E5%8F%AF%E9%80%89%E5%8F%82%E6%95%B0%E4%BB%A5%E5%8F%8A%20rest%20%E5%8F%82%E6%95%B0%EF%BC%8C%E8%BF%99%E6%9C%89%E4%B8%80%E4%B8%AA%E7%A8%8D%E5%BE%AE%E5%A4%8D%E6%9D%82%E7%9A%84%E4%BE%8B%E5%AD%90%EF%BC%9A%0A%60%60%60js%0Ainterface%20Complex%20%7B%0A%20%20(foo%3A%20string%2C%20bar%3F%3A%20number%2C%20...others%3A%20boolean%5B%5D)%3A%20number%3B%0A%7D%0A%60%60%60%0A%0A%E4%B8%80%E4%B8%AA%E6%8E%A5%E5%8F%A3%E5%8F%AF%E6%8F%90%E4%BE%9B%E5%A4%9A%E7%A7%8D%E8%B0%83%E7%94%A8%E7%AD%BE%E5%90%8D%EF%BC%8C%E7%94%A8%E4%BB%A5%E7%89%B9%E6%AE%8A%E7%9A%84%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD%EF%BC%9A%0A%60%60%60js%0Ainterface%20Overloaded%20%7B%0A%20%20(foo%3A%20string)%3A%20string%3B%0A%20%20(foo%3A%20number)%3A%20number%3B%0A%7D%0A%0A%2F%2F%20%E5%AE%9E%E7%8E%B0%E6%8E%A5%E5%8F%A3%E7%9A%84%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90%EF%BC%9A%0Afunction%20stringOrNumber(foo%3A%20number)%3A%20number%3B%0Afunction%20stringOrNumber(foo%3A%20string)%3A%20string%3B%0Afunction%20stringOrNumber(foo%3A%20any)%3A%20any%20%7B%0A%20%20if%20(typeof%20foo%20%3D%3D%3D%20'number')%20%7B%0A%20%20%20%20return%20foo%20*%20foo%3B%0A%20%20%7D%20else%20if%20(typeof%20foo%20%3D%3D%3D%20'string')%20%7B%0A%20%20%20%20return%20%60hello%20%24%7Bfoo%7D%60%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20overloaded%3A%20Overloaded%20%3D%20stringOrNumber%3B%0A%0A%2F%2F%20%E4%BD%BF%E7%94%A8%0Aconst%20str%20%3D%20overloaded('')%3B%20%2F%2F%20str%20%E8%A2%AB%E6%8E%A8%E6%96%AD%E4%B8%BA%20'string'%0Aconst%20num%20%3D%20overloaded(123)%3B%20%2F%2F%20num%20%E8%A2%AB%E6%8E%A8%E6%96%AD%E4%B8%BA%20'number'%0A%60%60%60%0A%0A%E8%BF%99%E4%B9%9F%E5%8F%AF%E4%BB%A5%E7%94%A8%E4%BA%8E%E5%86%85%E8%81%94%E6%B3%A8%E8%A7%A3%E4%B8%AD%EF%BC%9A%0A%60%60%60js%0Alet%20overloaded%3A%20%7B%0A%20%20(foo%3A%20string)%3A%20string%3B%0A%20%20(foo%3A%20number)%3A%20number%3B%0A%7D%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%0A%E4%B8%BA%E4%BA%86%E4%BD%BF%E6%8C%87%E5%AE%9A%E5%8F%AF%E8%B0%83%E7%94%A8%E7%9A%84%E7%B1%BB%E5%9E%8B%E7%AD%BE%E5%90%8D%E6%9B%B4%E5%AE%B9%E6%98%93%EF%BC%8CTypeScript%20%E4%B9%9F%E5%85%81%E8%AE%B8%E4%BD%A0%E4%BD%BF%E7%94%A8%E7%AE%80%E5%8D%95%E7%9A%84%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%8C%E5%9C%A8%E4%B8%80%E4%B8%AA%E4%BB%A5%20number%20%E7%B1%BB%E5%9E%8B%E4%B8%BA%E5%8F%82%E6%95%B0%EF%BC%8C%E4%BB%A5%20string%20%E7%B1%BB%E5%9E%8B%E4%B8%BA%E8%BF%94%E5%9B%9E%E5%80%BC%E7%9A%84%E5%87%BD%E6%95%B0%E4%B8%AD%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E8%BF%99%E4%B9%88%E5%86%99%EF%BC%9A%0A%60%60%60js%0Aconst%20simple%3A%20(foo%3A%20number)%20%3D%3E%20string%20%3D%20foo%20%3D%3E%20foo.toString()%3B%0A%60%60%60%0A*%E5%AE%83%E4%BB%85%E4%BB%85%E5%8F%AA%E8%83%BD%E4%BD%9C%E4%B8%BA%E7%AE%80%E5%8D%95%E7%9A%84%E7%AE%AD%E5%A4%B4%E5%87%BD%E6%95%B0%EF%BC%8C%E4%BD%A0%E6%97%A0%E6%B3%95%E4%BD%BF%E7%94%A8%E9%87%8D%E8%BD%BD%E3%80%82%E5%A6%82%E6%9E%9C%E6%83%B3%E4%BD%BF%E7%94%A8%E9%87%8D%E8%BD%BD%EF%BC%8C%E4%BD%A0%E5%BF%85%E9%A1%BB%E4%BD%BF%E7%94%A8%E5%AE%8C%E6%95%B4%E7%9A%84%20%7B%20(someArgs)%3A%20someReturn%20%7D%20%E7%9A%84%E8%AF%AD%E6%B3%95*%0A%0A%23%23%23%23%20%E5%8F%AF%E5%AE%9E%E4%BE%8B%E5%8C%96%0A%E5%8F%AF%E5%AE%9E%E4%BE%8B%E5%8C%96%E4%BB%85%E4%BB%85%E6%98%AF%E5%8F%AF%E8%B0%83%E7%94%A8%E7%9A%84%E4%B8%80%E7%A7%8D%E7%89%B9%E6%AE%8A%E6%83%85%E5%86%B5%EF%BC%8C%E5%AE%83%E4%BD%BF%E7%94%A8%20new%20%E4%BD%9C%E4%B8%BA%E5%89%8D%E7%BC%80%E3%80%82%E5%AE%83%E6%84%8F%E5%91%B3%E7%9D%80%E4%BD%A0%E9%9C%80%E8%A6%81%E4%BD%BF%E7%94%A8%20new%20%E5%85%B3%E9%94%AE%E5%AD%97%E5%8E%BB%E8%B0%83%E7%94%A8%E5%AE%83%EF%BC%9A%0A%60%60%60js%0Ainterface%20CallMeWithNewToGetString%20%7B%0A%20%20new%20()%3A%20string%3B%0A%7D%0A%0A%2F%2F%20%E4%BD%BF%E7%94%A8%0Adeclare%20const%20Foo%3A%20CallMeWithNewToGetString%3B%0Aconst%20bar%20%3D%20new%20Foo()%3B%20%2F%2F%20bar%20%E8%A2%AB%E6%8E%A8%E6%96%AD%E4%B8%BA%20string%20%E7%B1%BB%E5%9E%8B%0A%60%60%60%0A%0A%23%23%20%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%0ATypeScript%20%E5%85%81%E8%AE%B8%E4%BD%A0%E8%A6%86%E7%9B%96%E5%AE%83%E7%9A%84%E6%8E%A8%E6%96%AD%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%83%BD%E4%BB%A5%E4%BD%A0%E4%BB%BB%E4%BD%95%E4%BD%A0%E6%83%B3%E8%A6%81%E7%9A%84%E6%96%B9%E5%BC%8F%E5%88%86%E6%9E%90%E5%AE%83%EF%BC%8C%E8%BF%99%E7%A7%8D%E6%9C%BA%E5%88%B6%E8%A2%AB%E7%A7%B0%E4%B8%BA%E3%80%8C%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E3%80%8D%E3%80%82TypeScript%20%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E7%94%A8%E6%9D%A5%E5%91%8A%E8%AF%89%E7%BC%96%E8%AF%91%E5%99%A8%E4%BD%A0%E6%AF%94%E5%AE%83%E6%9B%B4%E4%BA%86%E8%A7%A3%E8%BF%99%E4%B8%AA%E7%B1%BB%E5%9E%8B%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%AE%83%E4%B8%8D%E5%BA%94%E8%AF%A5%E5%86%8D%E5%8F%91%E5%87%BA%E9%94%99%E8%AF%AF%E3%80%82%0A%0A%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E7%9A%84%E4%B8%80%E4%B8%AA%E5%B8%B8%E8%A7%81%E7%94%A8%E4%BE%8B%E6%98%AF%E5%BD%93%E4%BD%A0%E4%BB%8E%20JavaScript%20%E8%BF%81%E7%A7%BB%E5%88%B0%20TypeScript%20%E6%97%B6%EF%BC%9A%0A%60%60%60ts%0Aconst%20foo%20%3D%20%7B%7D%3B%0Afoo.bar%20%3D%20123%3B%20%2F%2F%20Error%3A%20'bar'%20%E5%B1%9E%E6%80%A7%E4%B8%8D%E5%AD%98%E5%9C%A8%E4%BA%8E%20%E2%80%98%7B%7D%E2%80%99%0Afoo.bas%20%3D%20'hello'%3B%20%2F%2F%20Error%3A%20'bas'%20%E5%B1%9E%E6%80%A7%E4%B8%8D%E5%AD%98%E5%9C%A8%E4%BA%8E%20'%7B%7D'%0A%60%60%60%0A%0A%E8%BF%99%E9%87%8C%E7%9A%84%E4%BB%A3%E7%A0%81%E5%8F%91%E5%87%BA%E4%BA%86%E9%94%99%E8%AF%AF%E8%AD%A6%E5%91%8A%EF%BC%8C%E5%9B%A0%E4%B8%BA%20foo%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%8E%A8%E6%96%AD%E4%B8%BA%20%7B%7D%EF%BC%8C%E5%8D%B3%E6%98%AF%E5%85%B7%E6%9C%89%E9%9B%B6%E5%B1%9E%E6%80%A7%E7%9A%84%E5%AF%B9%E8%B1%A1%E3%80%82%E5%9B%A0%E6%AD%A4%EF%BC%8C%E4%BD%A0%E4%B8%8D%E8%83%BD%E5%9C%A8%E5%AE%83%E7%9A%84%E5%B1%9E%E6%80%A7%E4%B8%8A%E6%B7%BB%E5%8A%A0%20bar%20%E6%88%96%20bas%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E6%9D%A5%E9%81%BF%E5%85%8D%E6%AD%A4%E9%97%AE%E9%A2%98%EF%BC%9A%0A%60%60%60ts%0Ainterface%20Foo%20%7B%0A%20%20bar%3A%20number%3B%0A%20%20bas%3A%20string%3B%0A%7D%0A%0Aconst%20foo%20%3D%20%7B%7D%20as%20Foo%3B%0Afoo.bar%20%3D%20123%3B%0Afoo.bas%20%3D%20'hello'%3B%0A%60%60%60%0A%0A%23%23%23%23%20as%20foo%20%E4%B8%8E%20%3Cfoo%3E%0A%0A%E6%9C%80%E5%88%9D%E7%9A%84%E6%96%AD%E8%A8%80%E8%AF%AD%E6%B3%95%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%EF%BC%9A%0A%60%60%60ts%0Alet%20foo%3A%20any%3B%0Alet%20bar%20%3D%20%3Cstring%3Efoo%3B%20%2F%2F%20%E7%8E%B0%E5%9C%A8%20bar%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%98%AF%20'string'%0A%60%60%60%0A%0A%E7%84%B6%E8%80%8C%EF%BC%8C%E5%BD%93%E4%BD%A0%E5%9C%A8%20JSX%20%E4%B8%AD%E4%BD%BF%E7%94%A8%20%3Cfoo%3E%20%E7%9A%84%E6%96%AD%E8%A8%80%E8%AF%AD%E6%B3%95%E6%97%B6%EF%BC%8C%E8%BF%99%E4%BC%9A%E4%B8%8E%20JSX%20%E7%9A%84%E8%AF%AD%E6%B3%95%E5%AD%98%E5%9C%A8%E6%AD%A7%E4%B9%89%EF%BC%9A%0A%60%60%60ts%0Alet%20foo%20%3D%20%3Cstring%3Ebar%3B%3C%2Fstring%3E%3B%0A%60%60%60%0A%E5%9B%A0%E6%AD%A4%EF%BC%8C%E4%B8%BA%E4%BA%86%E4%B8%80%E8%87%B4%E6%80%A7%EF%BC%8C%E6%88%91%E4%BB%AC%E5%BB%BA%E8%AE%AE%E4%BD%A0%E4%BD%BF%E7%94%A8%20as%20foo%20%E7%9A%84%E8%AF%AD%E6%B3%95%E6%9D%A5%E4%B8%BA%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E3%80%82%0A%0A%23%23%23%23%20%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E4%B8%8E%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%0A%E5%AE%83%E4%B9%8B%E6%89%80%E4%BB%A5%E4%B8%8D%E8%A2%AB%E7%A7%B0%E4%B8%BA%E3%80%8C%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%E3%80%8D%EF%BC%8C%E6%98%AF%E5%9B%A0%E4%B8%BA%E8%BD%AC%E6%8D%A2%E9%80%9A%E5%B8%B8%E6%84%8F%E5%91%B3%E7%9D%80%E6%9F%90%E7%A7%8D%E8%BF%90%E8%A1%8C%E6%97%B6%E7%9A%84%E6%94%AF%E6%8C%81%E3%80%82%E4%BD%86%E6%98%AF%EF%BC%8C%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E7%BA%AF%E7%B2%B9%E6%98%AF%E4%B8%80%E4%B8%AA%E7%BC%96%E8%AF%91%E6%97%B6%E8%AF%AD%E6%B3%95%EF%BC%8C%E5%90%8C%E6%97%B6%EF%BC%8C%E5%AE%83%E4%B9%9F%E6%98%AF%E4%B8%80%E7%A7%8D%E4%B8%BA%E7%BC%96%E8%AF%91%E5%99%A8%E6%8F%90%E4%BE%9B%E5%85%B3%E4%BA%8E%E5%A6%82%E4%BD%95%E5%88%86%E6%9E%90%E4%BB%A3%E7%A0%81%E7%9A%84%E6%96%B9%E6%B3%95%E3%80%82%0A%0A%23%23%23%23%20%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E8%A2%AB%E8%AE%A4%E4%B8%BA%E6%98%AF%E6%9C%89%E5%AE%B3%E7%9A%84%0A%E5%9C%A8%E5%BE%88%E5%A4%9A%E6%83%85%E6%99%AF%E4%B8%8B%EF%BC%8C%E6%96%AD%E8%A8%80%E8%83%BD%E8%AE%A9%E4%BD%A0%E6%9B%B4%E5%AE%B9%E6%98%93%E7%9A%84%E4%BB%8E%E9%81%97%E7%95%99%E9%A1%B9%E7%9B%AE%E4%B8%AD%E8%BF%81%E7%A7%BB%EF%BC%88%E7%94%9A%E8%87%B3%E5%B0%86%E5%85%B6%E4%BB%96%E4%BB%A3%E7%A0%81%E7%B2%98%E8%B4%B4%E5%A4%8D%E5%88%B6%E5%88%B0%E4%BD%A0%E7%9A%84%E9%A1%B9%E7%9B%AE%E4%B8%AD%EF%BC%89%EF%BC%8C%E7%84%B6%E8%80%8C%EF%BC%8C%E4%BD%A0%E5%BA%94%E8%AF%A5%E5%B0%8F%E5%BF%83%E8%B0%A8%E6%85%8E%E7%9A%84%E4%BD%BF%E7%94%A8%E6%96%AD%E8%A8%80%E3%80%82%E8%AE%A9%E6%88%91%E4%BB%AC%E7%94%A8%E6%9C%80%E5%88%9D%E7%9A%84%E4%BB%A3%E7%A0%81%E4%BD%9C%E4%B8%BA%E7%A4%BA%E4%BE%8B%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%B2%A1%E6%9C%89%E6%8C%89%E7%BA%A6%E5%AE%9A%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%EF%BC%8CTypeScript%20%E7%BC%96%E8%AF%91%E5%99%A8%E5%B9%B6%E4%B8%8D%E4%BC%9A%E5%AF%B9%E6%AD%A4%E5%8F%91%E5%87%BA%E9%94%99%E8%AF%AF%E8%AD%A6%E5%91%8A%EF%BC%9A%0A%60%60%60ts%0Ainterface%20Foo%20%7B%0A%20%20bar%3A%20number%3B%0A%20%20bas%3A%20string%3B%0A%7D%0A%0Aconst%20foo%20%3D%20%7B%7D%20as%20Foo%3B%0A%0A%2F%2F%20ahhh%2C%20%E5%BF%98%E8%AE%B0%E4%BA%86%E4%BB%80%E4%B9%88%EF%BC%9F%0A%60%60%60%0A%0A%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AA%E5%B8%B8%E8%A7%81%E7%9A%84%E6%83%B3%E6%B3%95%E6%98%AF%E4%BD%BF%E7%94%A8%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E6%9D%A5%E6%8F%90%E4%BE%9B%E4%BB%A3%E7%A0%81%E7%9A%84%E6%8F%90%E7%A4%BA%EF%BC%9A%0A%60%60%60ts%0Ainterface%20Foo%20%7B%0A%20%20bar%3A%20number%3B%0A%20%20bas%3A%20string%3B%0A%7D%0A%0Aconst%20foo%20%3D%20%3CFoo%3E%7B%0A%20%20%2F%2F%20%E7%BC%96%E8%AF%91%E5%99%A8%E5%B0%86%E4%BC%9A%E6%8F%90%E4%BE%9B%E5%85%B3%E4%BA%8E%20Foo%20%E5%B1%9E%E6%80%A7%E7%9A%84%E4%BB%A3%E7%A0%81%E6%8F%90%E7%A4%BA%0A%20%20%2F%2F%20%E4%BD%86%E6%98%AF%E5%BC%80%E5%8F%91%E4%BA%BA%E5%91%98%E4%B9%9F%E5%BE%88%E5%AE%B9%E6%98%93%E5%BF%98%E8%AE%B0%E6%B7%BB%E5%8A%A0%E6%89%80%E6%9C%89%E7%9A%84%E5%B1%9E%E6%80%A7%0A%20%20%2F%2F%20%E5%90%8C%E6%A0%B7%EF%BC%8C%E5%A6%82%E6%9E%9C%20Foo%20%E8%A2%AB%E9%87%8D%E6%9E%84%EF%BC%8C%E8%BF%99%E6%AE%B5%E4%BB%A3%E7%A0%81%E4%B9%9F%E5%8F%AF%E8%83%BD%E8%A2%AB%E7%A0%B4%E5%9D%8F%EF%BC%88%E4%BE%8B%E5%A6%82%EF%BC%8C%E4%B8%80%E4%B8%AA%E6%96%B0%E7%9A%84%E5%B1%9E%E6%80%A7%E8%A2%AB%E6%B7%BB%E5%8A%A0%EF%BC%89%E3%80%82%0A%7D%3B%0A%60%60%60%0A%0A%E8%BF%99%E4%B9%9F%E4%BC%9A%E5%AD%98%E5%9C%A8%E4%B8%80%E4%B8%AA%E5%90%8C%E6%A0%B7%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E5%BF%98%E8%AE%B0%E4%BA%86%E6%9F%90%E4%B8%AA%E5%B1%9E%E6%80%A7%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E5%90%8C%E6%A0%B7%E4%B9%9F%E4%B8%8D%E4%BC%9A%E5%8F%91%E5%87%BA%E9%94%99%E8%AF%AF%E8%AD%A6%E5%91%8A%E3%80%82%E4%BD%BF%E7%94%A8%E4%B8%80%E7%A7%8D%E6%9B%B4%E5%A5%BD%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%9A%0A%60%60%60ts%0Ainterface%20Foo%20%7B%0A%20%20bar%3A%20number%3B%0A%20%20bas%3A%20string%3B%0A%7D%0A%0Aconst%20foo%3A%20Foo%20%3D%20%7B%0A%20%20%2F%2F%20%E7%BC%96%E8%AF%91%E5%99%A8%E5%B0%86%E4%BC%9A%E6%8F%90%E4%BE%9B%20Foo%20%E5%B1%9E%E6%80%A7%E7%9A%84%E4%BB%A3%E7%A0%81%E6%8F%90%E7%A4%BA%0A%7D%3B%0A%60%60%60%0A%E5%9C%A8%E6%9F%90%E4%BA%9B%E6%83%85%E6%99%AF%E4%B8%8B%EF%BC%8C%E4%BD%A0%E5%8F%AF%E8%83%BD%E9%9C%80%E8%A6%81%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E4%B8%B4%E6%97%B6%E7%9A%84%E5%8F%98%E9%87%8F%EF%BC%8C%E4%BD%86%E8%87%B3%E5%B0%91%EF%BC%8C%E4%BD%A0%E4%B8%8D%E4%BC%9A%E4%BD%BF%E7%94%A8%E4%B8%80%E4%B8%AA%E6%89%BF%E8%AF%BA%EF%BC%88%E5%8F%AF%E8%83%BD%E6%98%AF%E5%81%87%E7%9A%84%EF%BC%89%EF%BC%8C%E8%80%8C%E6%98%AF%E4%BE%9D%E9%9D%A0%E7%B1%BB%E5%9E%8B%E6%8E%A8%E6%96%AD%E6%9D%A5%E6%A3%80%E6%9F%A5%E4%BD%A0%E7%9A%84%E4%BB%A3%E7%A0%81%E3%80%82%0A%0A%23%23%23%23%20%E5%8F%8C%E9%87%8D%E6%96%AD%E8%A8%80%0A%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%EF%BC%8C%E5%B0%BD%E7%AE%A1%E6%88%91%E4%BB%AC%E5%B7%B2%E7%BB%8F%E8%AF%81%E6%98%8E%E4%BA%86%E5%AE%83%E5%B9%B6%E4%B8%8D%E6%98%AF%E9%82%A3%E4%B9%88%E5%AE%89%E5%85%A8%EF%BC%8C%E4%BD%86%E5%AE%83%E4%B9%9F%E8%BF%98%E6%98%AF%E6%9C%89%E7%94%A8%E6%AD%A6%E4%B9%8B%E5%9C%B0%E3%80%82%E5%A6%82%E4%B8%8B%E4%B8%80%E4%B8%AA%E9%9D%9E%E5%B8%B8%E5%AE%9E%E7%94%A8%E7%9A%84%E4%BE%8B%E5%AD%90%E6%89%80%E7%A4%BA%EF%BC%8C%E5%BD%93%E4%BD%BF%E7%94%A8%E8%80%85%E4%BA%86%E8%A7%A3%E4%BC%A0%E5%85%A5%E5%8F%82%E6%95%B0%E6%9B%B4%E5%85%B7%E4%BD%93%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%97%B6%EF%BC%8C%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E8%83%BD%E6%8C%89%E9%A2%84%E6%9C%9F%E5%B7%A5%E4%BD%9C%EF%BC%9A%0A%60%60%60ts%0Afunction%20handler(event%3A%20Event)%20%7B%0A%20%20const%20mouseEvent%20%3D%20event%20as%20MouseEvent%3B%0A%7D%0A%60%60%60%0A%0A%E7%84%B6%E8%80%8C%EF%BC%8C%E5%A6%82%E4%B8%8B%E4%BE%8B%E5%AD%90%E4%B8%AD%E7%9A%84%E4%BB%A3%E7%A0%81%E5%B0%86%E4%BC%9A%E6%8A%A5%E9%94%99%EF%BC%8C%E5%B0%BD%E7%AE%A1%E4%BD%BF%E7%94%A8%E8%80%85%E5%B7%B2%E7%BB%8F%E4%BD%BF%E7%94%A8%E4%BA%86%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%EF%BC%9A%0A%60%60%60ts%0Afunction%20handler(event%3A%20Event)%20%7B%0A%20%20const%20element%20%3D%20event%20as%20HTMLElement%3B%20%2F%2F%20Error%3A%20'Event'%20%E5%92%8C%20'HTMLElement'%20%E4%B8%AD%E7%9A%84%E4%BB%BB%E4%BD%95%E4%B8%80%E4%B8%AA%E9%83%BD%E4%B8%8D%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AA%0A%7D%0A%60%60%60%0A%0A%E5%A6%82%E6%9E%9C%E4%BD%A0%E4%BB%8D%E7%84%B6%E6%83%B3%E4%BD%BF%E7%94%A8%E9%82%A3%E4%B8%AA%E7%B1%BB%E5%9E%8B%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E5%8F%8C%E9%87%8D%E6%96%AD%E8%A8%80%E3%80%82%E9%A6%96%E5%85%88%E6%96%AD%E8%A8%80%E6%88%90%E5%85%BC%E5%AE%B9%E6%89%80%E6%9C%89%E7%B1%BB%E5%9E%8B%E7%9A%84%20any%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E5%B0%86%E4%B8%8D%E4%BC%9A%E6%8A%A5%E9%94%99%EF%BC%9A%0A%60%60%60ts%0Afunction%20handler(event%3A%20Event)%20%7B%0A%20%20const%20element%20%3D%20(event%20as%20any)%20as%20HTMLElement%3B%20%2F%2F%20ok%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20TypeScript%20%E6%98%AF%E6%80%8E%E4%B9%88%E7%A1%AE%E5%AE%9A%E5%8D%95%E4%B8%AA%E6%96%AD%E8%A8%80%E6%98%AF%E5%90%A6%E8%B6%B3%E5%A4%9F%0A%E5%BD%93%20S%20%E7%B1%BB%E5%9E%8B%E6%98%AF%20T%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%AD%90%E9%9B%86%EF%BC%8C%E6%88%96%E8%80%85%20T%20%E7%B1%BB%E5%9E%8B%E6%98%AF%20S%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%AD%90%E9%9B%86%E6%97%B6%EF%BC%8CS%20%E8%83%BD%E8%A2%AB%E6%88%90%E5%8A%9F%E6%96%AD%E8%A8%80%E6%88%90%20T%E3%80%82%E8%BF%99%E6%98%AF%E4%B8%BA%E4%BA%86%E5%9C%A8%E8%BF%9B%E8%A1%8C%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E6%97%B6%E6%8F%90%E4%BE%9B%E9%A2%9D%E5%A4%96%E7%9A%84%E5%AE%89%E5%85%A8%E6%80%A7%EF%BC%8C%E5%AE%8C%E5%85%A8%E6%AF%AB%E6%97%A0%E6%A0%B9%E6%8D%AE%E7%9A%84%E6%96%AD%E8%A8%80%E6%98%AF%E5%8D%B1%E9%99%A9%E7%9A%84%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%83%B3%E8%BF%99%E4%B9%88%E5%81%9A%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%20any%E3%80%82%0A%0A%0A%23%23%20Freshness%0A%E4%B8%BA%E4%BA%86%E8%83%BD%E8%AE%A9%E6%A3%80%E6%9F%A5%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E7%B1%BB%E5%9E%8B%E6%9B%B4%E5%AE%B9%E6%98%93%EF%BC%8CTypeScript%20%E6%8F%90%E4%BE%9B%20%E3%80%8CFreshness%E3%80%8D%20%E7%9A%84%E6%A6%82%E5%BF%B5%EF%BC%88%E5%AE%83%E4%B9%9F%E8%A2%AB%E7%A7%B0%E4%B8%BA%E6%9B%B4%E4%B8%A5%E6%A0%BC%E7%9A%84%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E6%A3%80%E6%9F%A5%EF%BC%89%E7%94%A8%E6%9D%A5%E7%A1%AE%E4%BF%9D%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E5%9C%A8%E7%BB%93%E6%9E%84%E4%B8%8A%E7%B1%BB%E5%9E%8B%E5%85%BC%E5%AE%B9%E3%80%82%0A%0A%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E9%9D%9E%E5%B8%B8%E6%96%B9%E4%BE%BF%E3%80%82%E8%80%83%E8%99%91%E5%A6%82%E4%B8%8B%E4%BE%8B%E5%AD%90%E4%BB%A3%E7%A0%81%EF%BC%8C%E5%AE%83%E5%8F%AF%E4%BB%A5%E8%AE%A9%E4%BD%A0%E9%9D%9E%E5%B8%B8%E4%BE%BF%E5%88%A9%E7%9A%84%E4%BB%8E%20JavaScript%20%E8%BF%81%E7%A7%BB%E8%87%B3%20TypeScript%EF%BC%8C%E5%B9%B6%E4%B8%94%E4%BC%9A%E6%8F%90%E4%BE%9B%E7%B1%BB%E5%9E%8B%E5%AE%89%E5%85%A8%EF%BC%9A%0A%60%60%60ts%0Afunction%20logName(something%3A%20%7B%20name%3A%20string%20%7D)%20%7B%0A%20%20console.log(something.name)%3B%0A%7D%0A%0Aconst%20person%20%3D%20%7B%20name%3A%20'matt'%2C%20job%3A%20'being%20awesome'%20%7D%3B%0Aconst%20animal%20%3D%20%7B%20name%3A%20'cow'%2C%20diet%3A%20'vegan%2C%20but%20has%20milk%20of%20own%20specie'%20%7D%3B%0Aconst%20randow%20%3D%20%7B%20note%3A%20%60I%20don't%20have%20a%20name%20property%60%20%7D%3B%0A%0AlogName(person)%3B%20%2F%2F%20ok%0AlogName(animal)%3B%20%2F%2F%20ok%0AlogName(randow)%3B%20%2F%2F%20Error%3A%20%E6%B2%A1%E6%9C%89%20%60name%60%20%E5%B1%9E%E6%80%A7%0A%60%60%60%0A%0A%E4%BD%86%E6%98%AF%EF%BC%8C%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E6%9C%89%E4%B8%80%E4%B8%AA%E7%BC%BA%E7%82%B9%EF%BC%8C%E5%AE%83%E8%83%BD%E8%AF%AF%E5%AF%BC%E4%BD%A0%E8%AE%A4%E4%B8%BA%E6%9F%90%E4%BA%9B%E4%B8%9C%E8%A5%BF%E6%8E%A5%E6%94%B6%E7%9A%84%E6%95%B0%E6%8D%AE%E6%AF%94%E5%AE%83%E5%AE%9E%E9%99%85%E7%9A%84%E5%A4%9A%E3%80%82%E5%A6%82%E4%B8%8B%E4%BE%8B%EF%BC%8CTypeScript%20%E5%8F%91%E5%87%BA%E9%94%99%E8%AF%AF%E8%AD%A6%E5%91%8A%EF%BC%9A%0A%60%60%60ts%0Afunction%20logName(something%3A%20%7B%20name%3A%20string%20%7D)%20%7B%0A%20%20console.log(something.name)%3B%0A%7D%0A%0AlogName(%7B%20name%3A%20'matt'%20%7D)%3B%20%2F%2F%20ok%0AlogName(%7B%20name%3A%20'matt'%2C%20job%3A%20'being%20awesome'%20%7D)%3B%20%2F%2F%20Error%3A%20%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E5%8F%AA%E8%83%BD%E6%8C%87%E5%AE%9A%E5%B7%B2%E7%9F%A5%E5%B1%9E%E6%80%A7%EF%BC%8C%60job%60%20%E5%B1%9E%E6%80%A7%E5%9C%A8%E8%BF%99%E9%87%8C%E5%B9%B6%E4%B8%8D%E5%AD%98%E5%9C%A8%E3%80%82%0A%60%60%60%0A*%E8%AF%B7%E6%B3%A8%E6%84%8F%EF%BC%8C%E8%BF%99%E7%A7%8D%E9%94%99%E8%AF%AF%E6%8F%90%E7%A4%BA%EF%BC%8C%E5%8F%AA%E4%BC%9A%E5%8F%91%E7%94%9F%E5%9C%A8%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E4%B8%8A%E3%80%82*%0A%0A%0A%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AA%E4%BD%BF%E7%94%A8%E6%AF%94%E8%BE%83%E5%A4%9A%E7%9A%84%E5%9C%BA%E6%99%AF%E6%98%AF%E4%B8%8E%E5%85%B7%E6%9C%89%E5%8F%AF%E9%80%89%E6%88%90%E5%91%98%E7%9A%84%E6%8E%A5%E5%8F%A3%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%B2%A1%E6%9C%89%E8%BF%99%E6%A0%B7%E7%9A%84%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E6%A3%80%E6%9F%A5%EF%BC%8C%E5%BD%93%E4%BD%A0%E8%BE%93%E5%85%A5%E9%94%99%E8%AF%AF%E5%8D%95%E8%AF%8D%E7%9A%84%E6%97%B6%E5%80%99%EF%BC%8C%E5%B9%B6%E4%B8%8D%E4%BC%9A%E5%8F%91%E5%87%BA%E9%94%99%E8%AF%AF%E8%AD%A6%E5%91%8A%EF%BC%9A%0A%60%60%60ts%0Afunction%20logIfHasName(something%3A%20%7B%20name%3F%3A%20string%20%7D)%20%7B%0A%20%20if%20(something.name)%20%7B%0A%20%20%20%20console.log(something.name)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20person%20%3D%20%7B%20name%3A%20'matt'%2C%20job%3A%20'being%20awesome'%20%7D%3B%0Aconst%20animal%20%3D%20%7B%20name%3A%20'cow'%2C%20diet%3A%20'vegan%2C%20but%20has%20milk%20of%20own%20species'%20%7D%3B%0A%0AlogIfHasName(person)%3B%20%2F%2F%20okay%0AlogIfHasName(animal)%3B%20%2F%2F%20okay%0A%0AlogIfHasName(%7B%20neme%3A%20'I%20just%20misspelled%20name%20to%20neme'%20%7D)%3B%20%2F%2F%20Error%3A%20%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E5%8F%AA%E8%83%BD%E6%8C%87%E5%AE%9A%E5%B7%B2%E7%9F%A5%E5%B1%9E%E6%80%A7%EF%BC%8C%60neme%60%20%E5%B1%9E%E6%80%A7%E4%B8%8D%E5%AD%98%E5%9C%A8%E3%80%82%0A%60%60%60%0A%0A%23%23%23%23%20%E5%85%81%E8%AE%B8%E9%A2%9D%E5%A4%96%E7%9A%84%E5%B1%9E%E6%80%A7%0A%E4%B8%80%E4%B8%AA%E7%B1%BB%E5%9E%8B%E8%83%BD%E5%A4%9F%E5%8C%85%E5%90%AB%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%EF%BC%8C%E4%BB%A5%E6%98%8E%E7%A1%AE%E8%A1%A8%E6%98%8E%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E9%A2%9D%E5%A4%96%E7%9A%84%E5%B1%9E%E6%80%A7%3A%0A%60%60%60ts%0Alet%20x%3A%20%7B%20foo%3A%20number%2C%20%5Bx%3A%20string%5D%3A%20any%20%7D%3B%0A%0Ax%20%3D%20%7B%20foo%3A%201%2C%20baz%3A%202%20%7D%3B%20%2F%2F%20ok%2C%20'baz'%20%E5%B1%9E%E6%80%A7%E5%8C%B9%E9%85%8D%E4%BA%8E%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%0A%60%60%60%0A%0A%23%23%23%23%20%E7%94%A8%E4%BE%8B%EF%BC%9AReact%20State%0AFacebook%20ReactJS%20%E4%B8%BA%E5%AF%B9%E8%B1%A1%E7%9A%84%20Freshness%20%E6%8F%90%E4%BE%9B%E4%BA%86%E4%B8%80%E4%B8%AA%E5%BE%88%E5%A5%BD%E7%9A%84%E7%94%A8%E4%BE%8B%EF%BC%8C%E9%80%9A%E5%B8%B8%E5%9C%A8%E7%BB%84%E4%BB%B6%E4%B8%AD%EF%BC%8C%E4%BD%A0%E5%8F%AA%E4%BD%BF%E7%94%A8%E5%B0%91%E9%87%8F%E5%B1%9E%E6%80%A7%EF%BC%8C%E8%80%8C%E4%B8%8D%E6%98%AF%E4%BC%A0%E5%85%A5%E6%89%80%E6%9C%89%EF%BC%8C%E6%9D%A5%E8%B0%83%E7%94%A8%20setState%EF%BC%9A%0A%60%60%60ts%0A%2F%2F%20%E5%81%87%E8%AE%BE%0Ainterface%20State%20%7B%0A%20%20foo%3A%20string%3B%0A%20%20bar%3A%20string%3B%0A%7D%0A%0A%2F%2F%20%E4%BD%A0%E5%8F%AF%E8%83%BD%E6%83%B3%E5%81%9A%EF%BC%9A%0Athis.setState(%7B%20foo%3A%20'Hello'%20%7D)%3B%20%2F%2F%20Error%3A%20%E6%B2%A1%E6%9C%89%E5%B1%9E%E6%80%A7%20'bar'%0A%0A%2F%2F%20%E5%9B%A0%E4%B8%BA%20state%20%E5%8C%85%E5%90%AB%20'foo'%20%E4%B8%8E%20'bar'%EF%BC%8CTypeScript%20%E4%BC%9A%E5%BC%BA%E5%88%B6%E4%BD%A0%E8%BF%99%E4%B9%88%E5%81%9A%EF%BC%9A%0Athis.setState(%7B%20foo%3A%20'Hello'%2C%20bar%3A%20this.state.bar%20%7D)%3B%0A%0A%60%60%60%0A%0A%0A%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%83%B3%E4%BD%BF%E7%94%A8%20Freshness%EF%BC%8C%E4%BD%A0%E5%8F%AF%E8%83%BD%E9%9C%80%E8%A6%81%E5%B0%86%E6%89%80%E6%9C%89%E6%88%90%E5%91%98%E6%A0%87%E8%AE%B0%E4%B8%BA%E5%8F%AF%E9%80%89%EF%BC%8C%E8%BF%99%E4%BB%8D%E7%84%B6%E4%BC%9A%E6%8D%95%E6%8D%89%E5%88%B0%E6%8B%BC%E5%86%99%E9%94%99%E8%AF%AF%EF%BC%9A%0A%60%60%60ts%0A%2F%2F%20%E5%81%87%E8%AE%BE%0Ainterface%20State%20%7B%0A%20%20foo%3F%3A%20string%3B%0A%20%20bar%3F%3A%20string%3B%0A%7D%0A%0A%2F%2F%20%E4%BD%A0%E5%8F%AF%E8%83%BD%E6%83%B3%E5%81%9A%0Athis.setState(%7B%20foo%3A%20'Hello'%20%7D)%3B%20%2F%2F%20Yay%20works%20fine!%0A%0A%2F%2F%20%E7%94%B1%E4%BA%8E%20Freshness%EF%BC%8C%E4%BD%A0%E4%B9%9F%E5%8F%AF%E4%BB%A5%E9%98%B2%E6%AD%A2%E9%94%99%E5%88%AB%E5%AD%97%0Athis.setState(%7B%20foos%3A%20'Hello'%20%7D%7D%3B%20%2F%2F%20Error%3A%20%E5%AF%B9%E8%B1%A1%E5%8F%AA%E8%83%BD%E6%8C%87%E5%AE%9A%E5%B7%B2%E7%9F%A5%E5%B1%9E%E6%80%A7%0A%0A%2F%2F%20%E4%BB%8D%E7%84%B6%E4%BC%9A%E6%9C%89%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%9F%A5%0Athis.setState(%7B%20foo%3A%20123%20%7D%7D%3B%20%2F%2F%20Error%3A%20%E6%97%A0%E6%B3%95%E5%B0%86%20number%20%E7%B1%BB%E5%9E%8B%E8%B5%8B%E5%80%BC%E7%BB%99%20string%20%E7%B1%BB%E5%9E%8B%0A%60%60%60%0A%0A%23%23%20%E7%B1%BB%E5%9E%8B%E4%BF%9D%E6%8A%A4%0A%0A%23%23%23%23%20typeof%E5%92%8Cinstanceof%0A%0ATypeScript%20%E7%86%9F%E7%9F%A5%20JavaScript%20%E4%B8%AD%20instanceof%20%E5%92%8C%20typeof%20%E8%BF%90%E7%AE%97%E7%AC%A6%E7%9A%84%E7%94%A8%E6%B3%95%E3%80%82%E5%A6%82%E6%9E%9C%E4%BD%A0%E5%9C%A8%E4%B8%80%E4%B8%AA%E6%9D%A1%E4%BB%B6%E5%9D%97%E4%B8%AD%E4%BD%BF%E7%94%A8%E8%BF%99%E4%BA%9B%EF%BC%8CTypeScript%20%E5%B0%86%E4%BC%9A%E6%8E%A8%E5%AF%BC%E5%87%BA%E5%9C%A8%E6%9D%A1%E4%BB%B6%E5%9D%97%E4%B8%AD%E7%9A%84%E7%9A%84%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B%0A%60%60%60ts%0Afunction%20doSome(x%3A%20number%20%7C%20string)%20%7B%0A%20%20if%20(typeof%20x%20%3D%3D%3D%20'string')%20%7B%0A%20%20%20%20%2F%2F%20%E5%9C%A8%E8%BF%99%E4%B8%AA%E5%9D%97%E4%B8%AD%EF%BC%8CTypeScript%20%E7%9F%A5%E9%81%93%20%60x%60%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%BF%85%E9%A1%BB%E6%98%AF%20%60string%60%0A%20%20%20%20console.log(x.subtr(1))%3B%20%2F%2F%20Error%3A%20'subtr'%20%E6%96%B9%E6%B3%95%E5%B9%B6%E6%B2%A1%E6%9C%89%E5%AD%98%E5%9C%A8%E4%BA%8E%20%60string%60%20%E4%B8%8A%0A%20%20%20%20console.log(x.substr(1))%3B%20%2F%2F%20ok%0A%20%20%7D%0A%0A%20%20x.substr(1)%3B%20%2F%2F%20Error%3A%20%E6%97%A0%E6%B3%95%E4%BF%9D%E8%AF%81%20%60x%60%20%E6%98%AF%20%60string%60%20%E7%B1%BB%E5%9E%8B%0A%7D%0A%0A%2F%2F%E8%BF%99%E6%9C%89%E4%B8%80%E4%B8%AA%E5%85%B3%E4%BA%8E%20class%20%E5%92%8C%20instanceof%20%E7%9A%84%E4%BE%8B%E5%AD%90%EF%BC%9A%0Aclass%20Foo%20%7B%0A%20%20foo%20%3D%20123%3B%0A%20%20common%20%3D%20'123'%3B%0A%7D%0A%0Aclass%20Bar%20%7B%0A%20%20bar%20%3D%20123%3B%0A%20%20common%20%3D%20'123'%3B%0A%7D%0A%0Afunction%20doStuff(arg%3A%20Foo%20%7C%20Bar)%20%7B%0A%20%20if%20(arg%20instanceof%20Foo)%20%7B%0A%20%20%20%20console.log(arg.foo)%3B%20%2F%2F%20ok%0A%20%20%20%20console.log(arg.bar)%3B%20%2F%2F%20Error%0A%20%20%7D%0A%20%20if%20(arg%20instanceof%20Bar)%20%7B%0A%20%20%20%20console.log(arg.foo)%3B%20%2F%2F%20Error%0A%20%20%20%20console.log(arg.bar)%3B%20%2F%2F%20ok%0A%20%20%7D%0A%7D%0A%0AdoStuff(new%20Foo())%3B%0AdoStuff(new%20Bar())%3B%0A%0A%2F%2FTypeScript%20%E7%94%9A%E8%87%B3%E8%83%BD%E5%A4%9F%E7%90%86%E8%A7%A3%20else%E3%80%82%E5%BD%93%E4%BD%A0%E4%BD%BF%E7%94%A8%20if%20%E6%9D%A5%E7%BC%A9%E5%B0%8F%E7%B1%BB%E5%9E%8B%E6%97%B6%EF%BC%8CTypeScript%20%E7%9F%A5%E9%81%93%E5%9C%A8%E5%85%B6%E4%BB%96%E5%9D%97%E4%B8%AD%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%B9%B6%E4%B8%8D%E6%98%AF%20if%20%E4%B8%AD%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%9A%0Aclass%20Foo%20%7B%0A%20%20foo%20%3D%20123%3B%0A%7D%0A%0Aclass%20Bar%20%7B%0A%20%20bar%20%3D%20123%3B%0A%7D%0A%0Afunction%20doStuff(arg%3A%20Foo%20%7C%20Bar)%20%7B%0A%20%20if%20(arg%20instanceof%20Foo)%20%7B%0A%20%20%20%20console.log(arg.foo)%3B%20%2F%2F%20ok%0A%20%20%20%20console.log(arg.bar)%3B%20%2F%2F%20Error%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%2F%2F%20%E8%BF%99%E4%B8%AA%E5%9D%97%E4%B8%AD%EF%BC%8C%E4%B8%80%E5%AE%9A%E6%98%AF%20'Bar'%0A%20%20%20%20console.log(arg.foo)%3B%20%2F%2F%20Error%0A%20%20%20%20console.log(arg.bar)%3B%20%2F%2F%20ok%0A%20%20%7D%0A%7D%0A%0AdoStuff(new%20Foo())%3B%0AdoStuff(new%20Bar())%3B%0A%60%60%60%0A%0A%23%23%23%23%20in%0Ain%20%E6%93%8D%E4%BD%9C%E7%AC%A6%E5%8F%AF%E4%BB%A5%E5%AE%89%E5%85%A8%E7%9A%84%E6%A3%80%E6%9F%A5%E4%B8%80%E4%B8%AA%E5%AF%B9%E8%B1%A1%E4%B8%8A%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8%E4%B8%80%E4%B8%AA%E5%B1%9E%E6%80%A7%EF%BC%8C%E5%AE%83%E9%80%9A%E5%B8%B8%E4%B9%9F%E8%A2%AB%E4%BD%9C%E4%B8%BA%E7%B1%BB%E5%9E%8B%E4%BF%9D%E6%8A%A4%E4%BD%BF%E7%94%A8%EF%BC%9A%0A%60%60%60ts%0Ainterface%20A%20%7B%0A%20%20x%3A%20number%3B%0A%7D%0A%0Ainterface%20B%20%7B%0A%20%20y%3A%20string%3B%0A%7D%0A%0Afunction%20doStuff(q%3A%20A%20%7C%20B)%20%7B%0A%20%20if%20('x'%20in%20q)%20%7B%0A%20%20%20%20%2F%2F%20q%3A%20A%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%2F%2F%20q%3A%20B%0A%20%20%7D%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E5%AD%97%E9%9D%A2%E9%87%8F%E7%B1%BB%E5%9E%8B%E4%BF%9D%E6%8A%A4%0A%E5%BD%93%E4%BD%A0%E5%9C%A8%E8%81%94%E5%90%88%E7%B1%BB%E5%9E%8B%E9%87%8C%E4%BD%BF%E7%94%A8%E5%AD%97%E9%9D%A2%E9%87%8F%E7%B1%BB%E5%9E%8B%E6%97%B6%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E6%A3%80%E6%9F%A5%E5%AE%83%E4%BB%AC%E6%98%AF%E5%90%A6%E6%9C%89%E5%8C%BA%E5%88%AB%EF%BC%9A%0A%60%60%60ts%0Atype%20Foo%20%3D%20%7B%0A%20%20kind%3A%20'foo'%3B%20%2F%2F%20%E5%AD%97%E9%9D%A2%E9%87%8F%E7%B1%BB%E5%9E%8B%0A%20%20foo%3A%20number%3B%0A%7D%3B%0A%0Atype%20Bar%20%3D%20%7B%0A%20%20kind%3A%20'bar'%3B%20%2F%2F%20%E5%AD%97%E9%9D%A2%E9%87%8F%E7%B1%BB%E5%9E%8B%0A%20%20bar%3A%20number%3B%0A%7D%3B%0A%0Afunction%20doStuff(arg%3A%20Foo%20%7C%20Bar)%20%7B%0A%20%20if%20(arg.kind%20%3D%3D%3D%20'foo')%20%7B%0A%20%20%20%20console.log(arg.foo)%3B%20%2F%2F%20ok%0A%20%20%20%20console.log(arg.bar)%3B%20%2F%2F%20Error%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%2F%2F%20%E4%B8%80%E5%AE%9A%E6%98%AF%20Bar%0A%20%20%20%20console.log(arg.foo)%3B%20%2F%2F%20Error%0A%20%20%20%20console.log(arg.bar)%3B%20%2F%2F%20ok%0A%20%20%7D%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E4%BD%BF%E7%94%A8%E5%AE%9A%E4%B9%89%E7%9A%84%E7%B1%BB%E5%9E%8B%E4%BF%9D%E6%8A%A4%0AJavaScript%20%E5%B9%B6%E6%B2%A1%E6%9C%89%E5%86%85%E7%BD%AE%E9%9D%9E%E5%B8%B8%E4%B8%B0%E5%AF%8C%E7%9A%84%E3%80%81%E8%BF%90%E8%A1%8C%E6%97%B6%E7%9A%84%E8%87%AA%E6%88%91%E6%A3%80%E6%9F%A5%E6%9C%BA%E5%88%B6%E3%80%82%E5%BD%93%E4%BD%A0%E5%9C%A8%E4%BD%BF%E7%94%A8%E6%99%AE%E9%80%9A%E7%9A%84%20JavaScript%20%E5%AF%B9%E8%B1%A1%E6%97%B6%EF%BC%88%E4%BD%BF%E7%94%A8%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%EF%BC%8C%E6%9B%B4%E6%9C%89%E7%9B%8A%E5%A4%84%EF%BC%89%EF%BC%8C%E4%BD%A0%E7%94%9A%E8%87%B3%E6%97%A0%E6%B3%95%E8%AE%BF%E9%97%AE%20instanceof%20%E5%92%8C%20typeof%E3%80%82%E5%9C%A8%E8%BF%99%E7%A7%8D%E6%83%85%E6%99%AF%E4%B8%8B%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E5%88%9B%E5%BB%BA%E7%94%A8%E6%88%B7%E8%87%AA%E5%AE%9A%E4%B9%89%E7%9A%84%E7%B1%BB%E5%9E%8B%E4%BF%9D%E6%8A%A4%E5%87%BD%E6%95%B0%EF%BC%8C%E8%BF%99%E4%BB%85%E4%BB%85%E6%98%AF%E4%B8%80%E4%B8%AA%E8%BF%94%E5%9B%9E%E5%80%BC%E4%B8%BA%E7%B1%BB%E4%BC%BC%E4%BA%8EsomeArgumentName%20is%20SomeType%20%E7%9A%84%E5%87%BD%E6%95%B0%EF%BC%8C%E5%A6%82%E4%B8%8B%EF%BC%9A%0A%60%60%60js%0A%2F%2F%20%E4%BB%85%E4%BB%85%E6%98%AF%E4%B8%80%E4%B8%AA%20interface%0Ainterface%20Foo%20%7B%0A%20%20foo%3A%20number%3B%0A%20%20common%3A%20string%3B%0A%7D%0A%0Ainterface%20Bar%20%7B%0A%20%20bar%3A%20number%3B%0A%20%20common%3A%20string%3B%0A%7D%0A%0A%2F%2F%20%E7%94%A8%E6%88%B7%E8%87%AA%E5%B7%B1%E5%AE%9A%E4%B9%89%E7%9A%84%E7%B1%BB%E5%9E%8B%E4%BF%9D%E6%8A%A4%EF%BC%81%0Afunction%20isFoo(arg%3A%20Foo%20%7C%20Bar)%3A%20arg%20is%20Foo%20%7B%0A%20%20return%20(arg%20as%20Foo).foo%20!%3D%3D%20undefined%3B%0A%7D%0A%0A%2F%2F%20%E7%94%A8%E6%88%B7%E8%87%AA%E5%B7%B1%E5%AE%9A%E4%B9%89%E7%9A%84%E7%B1%BB%E5%9E%8B%E4%BF%9D%E6%8A%A4%E4%BD%BF%E7%94%A8%E7%94%A8%E4%BE%8B%EF%BC%9A%0Afunction%20doStuff(arg%3A%20Foo%20%7C%20Bar)%20%7B%0A%20%20if%20(isFoo(arg))%20%7B%0A%20%20%20%20console.log(arg.foo)%3B%20%2F%2F%20ok%0A%20%20%20%20console.log(arg.bar)%3B%20%2F%2F%20Error%0A%20%20%7D%20else%20%7B%0A%20%20%20%20console.log(arg.foo)%3B%20%2F%2F%20Error%0A%20%20%20%20console.log(arg.bar)%3B%20%2F%2F%20ok%0A%20%20%7D%0A%7D%0A%0AdoStuff(%7B%20foo%3A%20123%2C%20common%3A%20'123'%20%7D)%3B%0AdoStuff(%7B%20bar%3A%20123%2C%20common%3A%20'123'%20%7D)%3B%0A%60%60%60%0A%0A%23%23%20%E5%AD%97%E9%9D%A2%E9%87%8F%E7%B1%BB%E5%9E%8B%0A%0A%23%23%23%23%20%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%AD%97%E9%9D%A2%E9%87%8F%0A%E5%9C%A8%E8%BF%99%E9%87%8C%EF%BC%8C%E6%88%91%E4%BB%AC%E5%88%9B%E5%BB%BA%E4%BA%86%E4%B8%80%E4%B8%AA%E8%A2%AB%E7%A7%B0%E4%B8%BA%20foo%20%E5%8F%98%E9%87%8F%EF%BC%8C%E5%AE%83%E4%BB%85%E6%8E%A5%E6%94%B6%E4%B8%80%E4%B8%AA%E5%AD%97%E9%9D%A2%E9%87%8F%E5%80%BC%E4%B8%BA%20Hello%20%E7%9A%84%E5%8F%98%E9%87%8F%EF%BC%9A%0A%60%60%60ts%0Alet%20foo%3A%20'Hello'%3B%0Afoo%20%3D%20'Bar'%3B%20%2F%2F%20Error%3A%20'bar'%20%E4%B8%8D%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%E7%B1%BB%E5%9E%8B%20'Hello'%0A%60%60%60%0A%0A%E5%AE%83%E4%BB%AC%E6%9C%AC%E8%BA%AB%E5%B9%B6%E4%B8%8D%E6%98%AF%E5%BE%88%E5%AE%9E%E7%94%A8%EF%BC%8C%E4%BD%86%E6%98%AF%E5%8F%AF%E4%BB%A5%E5%9C%A8%E4%B8%80%E4%B8%AA%E8%81%94%E5%90%88%E7%B1%BB%E5%9E%8B%E4%B8%AD%E7%BB%84%E5%90%88%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%BC%BA%E5%A4%A7%E7%9A%84%EF%BC%88%E5%AE%9E%E7%94%A8%E7%9A%84%EF%BC%89%E6%8A%BD%E8%B1%A1%EF%BC%9A%0A%60%60%60ts%0Atype%20CardinalDirection%20%3D%20'North'%20%7C%20'East'%20%7C%20'South'%20%7C%20'West'%3B%0A%0Afunction%20move(distance%3A%20number%2C%20direction%3A%20CardinalDirection)%20%7B%0A%20%20%2F%2F%20...%0A%7D%0A%0Amove(1%2C%20'North')%3B%20%2F%2F%20ok%0Amove(1%2C%20'Nurth')%3B%20%2F%2F%20Error%0A%60%60%60%0A%0A%23%23%23%23%20%E5%85%B6%E4%BB%96%E5%AD%97%E9%9D%A2%E9%87%8F%E7%B1%BB%E5%9E%8B%0ATypeScript%20%E5%90%8C%E6%A0%B7%E4%B9%9F%E6%8F%90%E4%BE%9B%20boolean%20%E5%92%8C%20number%20%E7%9A%84%E5%AD%97%E9%9D%A2%E9%87%8F%E7%B1%BB%E5%9E%8B%EF%BC%9A%0A%60%60%60ts%0Atype%20OneToFive%20%3D%201%20%7C%202%20%7C%203%20%7C%204%20%7C%205%3B%0Atype%20Bools%20%3D%20true%20%7C%20false%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E6%8E%A8%E6%96%AD%0A%60%60%60ts%0Afunction%20iTakeFoo(foo%3A%20'foo')%20%7B%7D%0Aconst%20test%20%3D%20%7B%0A%20%20someProp%3A%20'foo'%0A%7D%3B%0A%0AiTakeFoo(test.someProp)%3B%20%2F%2F%20Error%3A%20Argument%20of%20type%20string%20is%20not%20assignable%20to%20parameter%20of%20type%20'foo'%0A%60%60%60%0A%E8%BF%99%E6%98%AF%E7%94%B1%E4%BA%8E%20test%20%E8%A2%AB%E6%8E%A8%E6%96%AD%E4%B8%BA%20%7B%20someProp%3A%20string%20%7D%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E9%87%87%E7%94%A8%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80%E6%9D%A5%E5%91%8A%E8%AF%89%20TypeScript%20%E4%BD%A0%E6%83%B3%E6%8E%A8%E6%96%AD%E7%9A%84%E5%AD%97%E9%9D%A2%E9%87%8F%EF%BC%9A%0A%0A%60%60%60ts%0Afunction%20iTakeFoo(foo%3A%20'foo')%20%7B%7D%0A%0Aconst%20test%20%3D%20%7B%0A%20%20someProp%3A%20'foo'%20as%20'foo'%0A%7D%3B%0A%0AiTakeFoo(test.someProp)%3B%20%2F%2F%20ok%0A%60%60%60%0A%0A%E6%88%96%E8%80%85%E4%BD%BF%E7%94%A8%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%8C%E6%9D%A5%E5%B8%AE%E5%8A%A9%20TypeScript%20%E6%8E%A8%E6%96%AD%E6%AD%A3%E7%A1%AE%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%9A%0A%60%60%60ts%0Afunction%20iTakeFoo(foo%3A%20'foo')%20%7B%7D%0A%0Atype%20Test%20%3D%20%7B%0A%20%20someProp%3A%20'foo'%3B%0A%7D%3B%0A%0Aconst%20test%3A%20Test%20%3D%20%7B%0A%20%20%2F%2F%20%E6%8E%A8%E6%96%AD%20%60someProp%60%20%E6%B0%B8%E8%BF%9C%E6%98%AF%20'foo'%0A%20%20someProp%3A%20'foo'%0A%7D%3B%0A%0AiTakeFoo(test.someProp)%3B%20%2F%2F%20ok%0A%60%60%60%0A%0A%23%23%23%23%20%E4%BD%BF%E7%94%A8%E7%94%A8%E4%BE%8B%0A%0A%60%60%60ts%0A%2F%2F%20%E7%94%A8%E4%BA%8E%E5%88%9B%E5%BB%BA%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%88%97%E8%A1%A8%E6%98%A0%E5%B0%84%E8%87%B3%20%60K%3A%20V%60%20%E7%9A%84%E5%87%BD%E6%95%B0%0Afunction%20strEnum%3CT%20extends%20string%3E(o%3A%20Array%3CT%3E)%3A%20%7B%20%5BK%20in%20T%5D%3A%20K%20%7D%20%7B%0A%20%20return%20o.reduce((res%2C%20key)%20%3D%3E%20%7B%0A%20%20%20%20res%5Bkey%5D%20%3D%20key%3B%0A%20%20%20%20return%20res%3B%0A%20%20%7D%2C%20Object.create(null))%3B%0A%7D%0A%0A%2F%2F%20%E5%88%9B%E5%BB%BA%20K%3A%20V%0Aconst%20Direction%20%3D%20strEnum(%5B'North'%2C%20'South'%2C%20'East'%2C%20'West'%5D)%3B%0A%0A%2F%2F%E4%BD%BF%E7%94%A8%20keyof%E3%80%81typeof%20%E6%9D%A5%E7%94%9F%E6%88%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E8%81%94%E5%90%88%E7%B1%BB%E5%9E%8B%0Atype%20Direction%20%3D%20keyof%20typeof%20Direction%3B%0A%0A%2F%2F%20%E7%AE%80%E5%8D%95%E7%9A%84%E4%BD%BF%E7%94%A8%0Alet%20sample%3A%20Direction%3B%0A%0Asample%20%3D%20Direction.North%3B%20%2F%2F%20Okay%0Asample%20%3D%20'North'%3B%20%2F%2F%20Okay%0Asample%20%3D%20'AnythingElse'%3B%20%2F%2F%20ERROR!%0A%60%60%60%0A%0A%23%23%20readonly%0ATypeScript%20%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F%E5%85%81%E8%AE%B8%E4%BD%A0%E5%9C%A8%E4%B8%80%E4%B8%AA%E6%8E%A5%E5%8F%A3%E9%87%8C%E4%BD%BF%E7%94%A8%20readonly%20%E6%9D%A5%E6%A0%87%E8%AE%B0%E5%B1%9E%E6%80%A7%E3%80%82%E5%AE%83%E8%83%BD%E8%AE%A9%E4%BD%A0%E4%BB%A5%E4%B8%80%E7%A7%8D%E6%9B%B4%E5%AE%89%E5%85%A8%E7%9A%84%E6%96%B9%E5%BC%8F%E5%B7%A5%E4%BD%9C%EF%BC%88%E4%B8%8D%E5%8F%AF%E9%A2%84%E6%9C%9F%E7%9A%84%E6%94%B9%E5%8F%98%E6%98%AF%E5%BE%88%E7%B3%9F%E7%B3%95%E7%9A%84%EF%BC%89%EF%BC%9A%0A%60%60%60ts%0Afunction%20foo(config%3A%20%7B%20readonly%20bar%3A%20number%2C%20readonly%20bas%3A%20number%20%7D)%20%7B%0A%20%20%2F%2F%20..%0A%7D%0A%0Aconst%20config%20%3D%20%7B%20bar%3A%20123%2C%20bas%3A%20123%20%7D%3B%0Afoo(config)%3B%0A%0A%2F%2F%20%E7%8E%B0%E5%9C%A8%E4%BD%A0%E8%83%BD%E5%A4%9F%E7%A1%AE%E4%BF%9D%20'config'%20%E4%B8%8D%E8%83%BD%E5%A4%9F%E8%A2%AB%E6%94%B9%E5%8F%98%E4%BA%86%0A%60%60%60%0A%E5%BD%93%E7%84%B6%EF%BC%8C%E4%BD%A0%E4%B9%9F%E5%8F%AF%E4%BB%A5%E5%9C%A8%20interface%20%E5%92%8C%20type%20%E9%87%8C%E4%BD%BF%E7%94%A8%20readonly%EF%BC%9A%0A%60%60%60ts%0Atype%20Foo%20%3D%20%7B%0A%20%20readonly%20bar%3A%20number%3B%0A%20%20readonly%20bas%3A%20number%3B%0A%7D%3B%0A%0A%2F%2F%20%E5%88%9D%E5%A7%8B%E5%8C%96%0Aconst%20foo%3A%20Foo%20%3D%20%7B%20bar%3A%20123%2C%20bas%3A%20456%20%7D%3B%0A%0A%2F%2F%20%E4%B8%8D%E8%83%BD%E8%A2%AB%E6%94%B9%E5%8F%98%0Afoo.bar%20%3D%20456%3B%20%2F%2F%20Error%3A%20foo.bar%20%E4%B8%BA%E4%BB%85%E8%AF%BB%E5%B1%9E%E6%80%A7%0A%60%60%60%0A%0A%E4%BD%A0%E4%B9%9F%E8%83%BD%E6%8C%87%E5%AE%9A%E4%B8%80%E4%B8%AA%E7%B1%BB%E7%9A%84%E5%B1%9E%E6%80%A7%E4%B8%BA%E5%8F%AA%E8%AF%BB%EF%BC%8C%E7%84%B6%E5%90%8E%E5%9C%A8%E5%A3%B0%E6%98%8E%E6%97%B6%E6%88%96%E8%80%85%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E4%B8%AD%E5%88%9D%E5%A7%8B%E5%8C%96%E5%AE%83%E4%BB%AC%EF%BC%8C%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%EF%BC%9A%0A%60%60%60ts%0Aclass%20Foo%20%7B%0A%20%20readonly%20bar%20%3D%201%3B%20%2F%2F%20OK%0A%20%20readonly%20baz%3A%20string%3B%0A%20%20constructor()%20%7B%0A%20%20%20%20this.baz%20%3D%20'hello'%3B%20%2F%2F%20OK%0A%20%20%7D%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E7%BB%9D%E5%AF%B9%E7%9A%84%E4%B8%8D%E5%8F%AF%E5%8F%98%0A%E4%BD%A0%E7%94%9A%E8%87%B3%E5%8F%AF%E4%BB%A5%E6%8A%8A%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E6%A0%87%E8%AE%B0%E4%B8%BA%E5%8F%AA%E8%AF%BB%EF%BC%9A%0A%60%60%60ts%0Ainterface%20Foo%20%7B%0A%20%20readonly%20%5Bx%3A%20number%5D%3A%20number%3B%0A%7D%0A%0A%2F%2F%20%E4%BD%BF%E7%94%A8%0A%0Aconst%20foo%3A%20Foo%20%3D%20%7B%200%3A%20123%2C%202%3A%20345%20%7D%3B%0Aconsole.log(foo%5B0%5D)%3B%20%2F%2F%20ok%EF%BC%88%E8%AF%BB%E5%8F%96%EF%BC%89%0Afoo%5B0%5D%20%3D%20456%3B%20%2F%2F%20Error%3A%20%E5%B1%9E%E6%80%A7%E5%8F%AA%E8%AF%BB%0A%60%60%60%0A%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%83%B3%E4%BB%A5%E4%B8%8D%E5%8F%98%E7%9A%84%E6%96%B9%E5%BC%8F%E4%BD%BF%E7%94%A8%E5%8E%9F%E7%94%9F%20JavaScript%20%E6%95%B0%E7%BB%84%EF%BC%8C%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%20TypeScript%20%E6%8F%90%E4%BE%9B%E7%9A%84%20ReadonlyArray%3CT%3E%20%E6%8E%A5%E5%8F%A3%EF%BC%9A%0A%60%60%60ts%0Alet%20foo%3A%20ReadonlyArray%3Cnumber%3E%20%3D%20%5B1%2C%202%2C%203%5D%3B%0Aconsole.log(foo%5B0%5D)%3B%20%2F%2F%20ok%0Afoo.push(4)%3B%20%2F%2F%20Error%3A%20ReadonlyArray%20%E4%B8%8A%E4%B8%8D%E5%AD%98%E5%9C%A8%20%60push%60%EF%BC%8C%E5%9B%A0%E4%B8%BA%E4%BB%96%E4%BC%9A%E6%94%B9%E5%8F%98%E6%95%B0%E7%BB%84%0Afoo%20%3D%20foo.concat(4)%3B%20%2F%2F%20ok%2C%20%E5%88%9B%E5%BB%BA%E4%BA%86%E4%B8%80%E4%B8%AA%E5%A4%8D%E5%88%B6%0A%60%60%60%0A%0A%23%23%23%23%20%E8%87%AA%E5%8A%A8%E6%8E%A8%E6%96%AD%0A%E5%9C%A8%E4%B8%80%E4%BA%9B%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E7%BC%96%E8%AF%91%E5%99%A8%E8%83%BD%E6%8A%8A%E4%B8%80%E4%BA%9B%E7%89%B9%E5%AE%9A%E7%9A%84%E5%B1%9E%E6%80%A7%E6%8E%A8%E6%96%AD%E4%B8%BA%20readonly%EF%BC%8C%E4%BE%8B%E5%A6%82%E5%9C%A8%E4%B8%80%E4%B8%AA%20class%20%E4%B8%AD%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%9C%89%E4%B8%80%E4%B8%AA%E5%8F%AA%E5%90%AB%E6%9C%89%20getter%20%E4%BD%86%E6%98%AF%E6%B2%A1%E6%9C%89%20setter%20%E7%9A%84%E5%B1%9E%E6%80%A7%EF%BC%8C%E4%BB%96%E8%83%BD%E8%A2%AB%E6%8E%A8%E6%96%AD%E4%B8%BA%E5%8F%AA%E8%AF%BB%EF%BC%9A%0A%60%60%60ts%0Aclass%20Person%20%7B%0A%20%20firstName%3A%20string%20%3D%20'John'%3B%0A%20%20lastName%3A%20string%20%3D%20'Doe'%3B%0A%0A%20%20get%20fullName()%20%7B%0A%20%20%20%20return%20this.firstName%20%2B%20this.lastName%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20person%20%3D%20new%20Person()%3B%0A%0Aconsole.log(person.fullName)%3B%20%2F%2F%20John%20Doe%0Aperson.fullName%20%3D%20'Dear%20Reader'%3B%20%2F%2F%20Error%2C%20fullName%20%E5%8F%AA%E8%AF%BB%0A%60%60%60%0A%0A%23%23%23%23%20%E4%B8%8E%20const%20%E7%9A%84%E4%B8%8D%E5%90%8C%0A%0Aconst%0A1.%E7%94%A8%E4%BA%8E%E5%8F%98%E9%87%8F%EF%BC%9B%0A2.%E5%8F%98%E9%87%8F%E4%B8%8D%E8%83%BD%E9%87%8D%E6%96%B0%E8%B5%8B%E5%80%BC%E7%BB%99%E5%85%B6%E4%BB%96%E4%BB%BB%E4%BD%95%E4%BA%8B%E7%89%A9%E3%80%82%0A%0Areadonly%0A1.%E7%94%A8%E4%BA%8E%E5%B1%9E%E6%80%A7%EF%BC%9B%0A2.%E7%94%A8%E4%BA%8E%E5%88%AB%E5%90%8D%EF%BC%8C%E5%8F%AF%E4%BB%A5%E4%BF%AE%E6%94%B9%E5%B1%9E%E6%80%A7%EF%BC%9B%0A%60%60%60ts%0Aconst%20foo%3A%20%7B%0A%20%20readonly%20bar%3A%20number%3B%0A%7D%20%3D%20%7B%0A%20%20bar%3A%20123%0A%7D%3B%0A%0Afunction%20iMutateFoo(foo%3A%20%7B%20bar%3A%20number%20%7D)%20%7B%0A%20%20foo.bar%20%3D%20456%3B%0A%7D%0A%0AiMutateFoo(foo)%3B%0Aconsole.log(foo.bar)%3B%20%2F%2F%20456%0A%60%60%60%0A%0A*readonly%20%E8%83%BD%E7%A1%AE%E4%BF%9D%E2%80%9C%E6%88%91%E2%80%9D%E4%B8%8D%E8%83%BD%E4%BF%AE%E6%94%B9%E5%B1%9E%E6%80%A7%EF%BC%8C%E4%BD%86%E6%98%AF%E5%BD%93%E4%BD%A0%E6%8A%8A%E8%BF%99%E4%B8%AA%E5%B1%9E%E6%80%A7%E4%BA%A4%E7%BB%99%E5%85%B6%E4%BB%96%E5%B9%B6%E6%B2%A1%E6%9C%89%E8%BF%99%E7%A7%8D%E4%BF%9D%E8%AF%81%E7%9A%84%E4%BD%BF%E7%94%A8%E8%80%85%EF%BC%88%E5%85%81%E8%AE%B8%E5%87%BA%E4%BA%8E%E7%B1%BB%E5%9E%8B%E5%85%BC%E5%AE%B9%E6%80%A7%E7%9A%84%E5%8E%9F%E5%9B%A0%EF%BC%89%EF%BC%8C%E4%BB%96%E4%BB%AC%E8%83%BD%E6%94%B9%E5%8F%98%E5%AE%83%E3%80%82*%0A%0A%23%23%20%E6%B3%9B%E5%9E%8B%0A%E6%B3%9B%E5%9E%8B%E7%9A%84%E5%85%B3%E9%94%AE%E7%9B%AE%E7%9A%84%E6%98%AF%E5%9C%A8%E6%88%90%E5%91%98%E4%B9%8B%E9%97%B4%E6%8F%90%E4%BE%9B%E6%9C%89%E6%84%8F%E4%B9%89%E7%9A%84%E7%BA%A6%E6%9D%9F%0A%0A%E4%B8%8B%E9%9D%A2%E6%98%AF%E5%AF%B9%E4%B8%80%E4%B8%AA%E5%85%88%E8%BF%9B%E5%85%88%E5%87%BA%E7%9A%84%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E2%80%94%E2%80%94%E9%98%9F%E5%88%97%EF%BC%8C%E5%9C%A8%20TypeScript%20%E5%92%8C%20JavaScript%20%E4%B8%AD%E7%9A%84%E7%AE%80%E5%8D%95%E5%AE%9E%E7%8E%B0%E3%80%82%0A%60%60%60ts%0Aclass%20Queue%20%7B%0A%20%20private%20data%20%3D%20%5B%5D%3B%0A%20%20push%20%3D%20item%20%3D%3E%20this.data.push(item)%3B%0A%20%20pop%20%3D%20()%20%3D%3E%20this.data.shift()%3B%0A%7D%0A%60%60%60%0A%E5%9C%A8%E4%B8%8A%E8%BF%B0%E4%BB%A3%E7%A0%81%E4%B8%AD%E5%AD%98%E5%9C%A8%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98%EF%BC%8C%E5%AE%83%E5%85%81%E8%AE%B8%E4%BD%A0%E5%90%91%E9%98%9F%E5%88%97%E4%B8%AD%E6%B7%BB%E5%8A%A0%E4%BB%BB%E4%BD%95%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%95%B0%E6%8D%AE%EF%BC%8C%E5%BD%93%E7%84%B6%EF%BC%8C%E5%BD%93%E6%95%B0%E6%8D%AE%E8%A2%AB%E5%BC%B9%E5%87%BA%E9%98%9F%E5%88%97%E6%97%B6%EF%BC%8C%E4%B9%9F%E5%8F%AF%E4%BB%A5%E6%98%AF%E4%BB%BB%E6%84%8F%E7%B1%BB%E5%9E%8B%E3%80%82%E5%9C%A8%E4%B8%8B%E9%9D%A2%E7%9A%84%E7%A4%BA%E4%BE%8B%E4%B8%AD%EF%BC%8C%E7%9C%8B%E8%B5%B7%E6%9D%A5%E4%BA%BA%E4%BB%AC%E5%8F%AF%E4%BB%A5%E5%90%91%E9%98%9F%E5%88%97%E4%B8%AD%E6%B7%BB%E5%8A%A0string%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%95%B0%E6%8D%AE%EF%BC%8C%E4%BD%86%E6%98%AF%E5%AE%9E%E9%99%85%E4%B8%8A%EF%BC%8C%E8%AF%A5%E7%94%A8%E6%B3%95%E5%81%87%E5%AE%9A%E7%9A%84%E6%98%AF%E5%8F%AA%E6%9C%89%20number%20%E7%B1%BB%E5%9E%8B%E4%BC%9A%E8%A2%AB%E6%B7%BB%E5%8A%A0%E5%88%B0%E9%98%9F%E5%88%97%E9%87%8C%E3%80%82%0A%60%60%60ts%0Aclass%20Queue%20%7B%0A%20%20private%20data%20%3D%20%5B%5D%3B%0A%20%20push%20%3D%20item%20%3D%3E%20this.data.push(item)%3B%0A%20%20pop%20%3D%20()%20%3D%3E%20this.data.shift()%3B%0A%7D%0A%0Aconst%20queue%20%3D%20new%20Queue()%3B%0A%0Aqueue.push(0)%3B%0Aqueue.push('1')%3B%20%2F%2F%20Oops%EF%BC%8C%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF%0A%0A%2F%2F%20%E4%B8%80%E4%B8%AA%E4%BD%BF%E7%94%A8%E8%80%85%EF%BC%8C%E8%B5%B0%E5%85%A5%E4%BA%86%E8%AF%AF%E5%8C%BA%0Aconsole.log(queue.pop().toPrecision(1))%3B%0Aconsole.log(queue.pop().toPrecision(1))%3B%20%2F%2F%20RUNTIME%20ERROR%0A%60%60%60%0A%0A%E4%B8%80%E4%B8%AA%E8%A7%A3%E5%86%B3%E7%9A%84%E5%8A%9E%E6%B3%95%EF%BC%88%E4%BA%8B%E5%AE%9E%E4%B8%8A%EF%BC%8C%E8%BF%99%E4%B9%9F%E6%98%AF%E4%B8%8D%E6%94%AF%E6%8C%81%E6%B3%9B%E5%9E%8B%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%94%AF%E4%B8%80%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95%EF%BC%89%E6%98%AF%E4%B8%BA%E8%BF%99%E4%BA%9B%E7%BA%A6%E6%9D%9F%E5%88%9B%E5%BB%BA%E7%89%B9%E6%AE%8A%E7%B1%BB%EF%BC%8C%E5%A6%82%E5%BF%AB%E9%80%9F%E5%88%9B%E5%BB%BA%E6%95%B0%E5%AD%97%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%98%9F%E5%88%97%EF%BC%9A%0A%60%60%60ts%0Aclass%20QueueNumber%20%7B%0A%20%20private%20data%20%3D%20%5B%5D%3B%0A%20%20push%20%3D%20(item%3A%20number)%20%3D%3E%20this.data.push(item)%3B%0A%20%20pop%20%3D%20()%3A%20number%20%3D%3E%20this.data.shift()%3B%0A%7D%0A%0Aconst%20queue%20%3D%20new%20QueueNumber()%3B%0A%0Aqueue.push(0)%3B%0Aqueue.push('1')%3B%20%2F%2F%20Error%3A%20%E4%B8%8D%E8%83%BD%E6%8E%A8%E5%85%A5%E4%B8%80%E4%B8%AA%20%60string%60%20%E7%B1%BB%E5%9E%8B%EF%BC%8C%E5%8F%AA%E8%83%BD%E6%98%AF%20%60number%60%20%E7%B1%BB%E5%9E%8B%0A%0A%2F%2F%20%E5%A6%82%E6%9E%9C%E8%AF%A5%E9%94%99%E8%AF%AF%E5%BE%97%E5%88%B0%E4%BF%AE%E5%A4%8D%EF%BC%8C%E5%85%B6%E4%BB%96%E5%B0%86%E4%B8%8D%E4%BC%9A%E5%87%BA%E7%8E%B0%E9%97%AE%E9%A2%98%0A%60%60%60%0A%E5%BD%93%E7%84%B6%EF%BC%8C%E5%BF%AB%E9%80%9F%E4%B9%9F%E6%84%8F%E5%91%B3%E7%9D%80%E7%97%9B%E8%8B%A6%E3%80%82%E4%BE%8B%E5%A6%82%E5%BD%93%E4%BD%A0%E6%83%B3%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E9%98%9F%E5%88%97%E6%97%B6%EF%BC%8C%E4%BD%A0%E5%B0%86%E4%B8%8D%E5%BE%97%E4%B8%8D%E5%86%8D%E6%AC%A1%E4%BF%AE%E6%94%B9%E7%9B%B8%E5%BD%93%E5%A4%A7%E7%9A%84%E4%BB%A3%E7%A0%81%E3%80%82%E6%88%91%E4%BB%AC%E7%9C%9F%E6%AD%A3%E6%83%B3%E8%A6%81%E7%9A%84%E4%B8%80%E7%A7%8D%E6%96%B9%E5%BC%8F%E6%98%AF%E6%97%A0%E8%AE%BA%E4%BB%80%E4%B9%88%E7%B1%BB%E5%9E%8B%E8%A2%AB%E6%8E%A8%E5%85%A5%E9%98%9F%E5%88%97%EF%BC%8C%E8%A2%AB%E6%8E%A8%E5%87%BA%E7%9A%84%E7%B1%BB%E5%9E%8B%E9%83%BD%E4%B8%8E%E6%8E%A8%E5%85%A5%E7%B1%BB%E5%9E%8B%E4%B8%80%E6%A0%B7%E3%80%82%E5%BD%93%E4%BD%A0%E4%BD%BF%E7%94%A8%E6%B3%9B%E5%9E%8B%E6%97%B6%EF%BC%8C%E8%BF%99%E4%BC%9A%E5%BE%88%E5%AE%B9%E6%98%93%EF%BC%9A%0A%60%60%60ts%0A%2F%2F%20%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E6%B3%9B%E5%9E%8B%E7%B1%BB%0Aclass%20Queue%3CT%3E%20%7B%0A%20%20private%20data%3A%20T%5B%5D%20%3D%20%5B%5D%3B%0A%20%20push%20%3D%20(item%3A%20T)%20%3D%3E%20this.data.push(item)%3B%0A%20%20pop%20%3D%20()%3A%20T%20%7C%20undefined%20%3D%3E%20this.data.shift()%3B%0A%7D%0A%0A%2F%2F%20%E7%AE%80%E5%8D%95%E7%9A%84%E4%BD%BF%E7%94%A8%0Aconst%20queue%20%3D%20new%20Queue%3Cnumber%3E()%3B%0Aqueue.push(0)%3B%0Aqueue.push('1')%3B%20%2F%2F%20Error%EF%BC%9A%E4%B8%8D%E8%83%BD%E6%8E%A8%E5%85%A5%E4%B8%80%E4%B8%AA%20%60string%60%EF%BC%8C%E5%8F%AA%E6%9C%89%20number%20%E7%B1%BB%E5%9E%8B%E8%A2%AB%E5%85%81%E8%AE%B8%0A%60%60%60%0A%0A%23%23%23%23%20%E8%AF%AF%E7%94%A8%E7%9A%84%E6%B3%9B%E5%9E%8B%0A%E6%88%91%E8%A7%81%E8%BF%87%E5%BC%80%E5%8F%91%E8%80%85%E4%BD%BF%E7%94%A8%E6%B3%9B%E5%9E%8B%E4%BB%85%E4%BB%85%E6%98%AF%E4%B8%BA%E4%BA%86%E5%AE%83%E7%9A%84%20hack%E3%80%82%E5%BD%93%E4%BD%A0%E4%BD%BF%E7%94%A8%E5%AE%83%E6%97%B6%EF%BC%8C%E4%BD%A0%E5%BA%94%E8%AF%A5%E9%97%AE%E9%97%AE%E8%87%AA%E5%B7%B1%EF%BC%9A%E4%BD%A0%E6%83%B3%E7%94%A8%E5%AE%83%E6%9D%A5%E6%8F%90%E4%BE%9B%E4%BB%80%E4%B9%88%E6%A0%B7%E7%9A%84%E7%BA%A6%E6%9D%9F%E3%80%82%E5%A6%82%E6%9E%9C%E4%BD%A0%E4%B8%8D%E8%83%BD%E5%BE%88%E5%A5%BD%E7%9A%84%E5%9B%9E%E7%AD%94%E5%AE%83%EF%BC%8C%E4%BD%A0%E5%8F%AF%E8%83%BD%E4%BC%9A%E8%AF%AF%E7%94%A8%E6%B3%9B%E5%9E%8B%EF%BC%8C%E5%A6%82%EF%BC%9A%0A%60%60%60ts%0Adeclare%20function%20foo%3CT%3E(arg%3A%20T)%3A%20void%3B%0A%60%60%60%0A%E5%9C%A8%E8%BF%99%E9%87%8C%EF%BC%8C%E6%B3%9B%E5%9E%8B%E5%AE%8C%E5%85%A8%E6%B2%A1%E6%9C%89%E5%BF%85%E8%A6%81%E4%BD%BF%E7%94%A8%EF%BC%8C%E5%9B%A0%E4%B8%BA%E5%AE%83%E4%BB%85%E7%94%A8%E4%BA%8E%E5%8D%95%E4%B8%AA%E5%8F%82%E6%95%B0%E7%9A%84%E4%BD%8D%E7%BD%AE%EF%BC%8C%E4%BD%BF%E7%94%A8%E5%A6%82%E4%B8%8B%E6%96%B9%E5%BC%8F%E5%8F%AF%E8%83%BD%E6%9B%B4%E5%A5%BD%EF%BC%9A%0A%60%60%60ts%0Adeclare%20function%20foo(arg%3A%20any)%3A%20void%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E9%85%8D%E5%90%88%20axios%20%E4%BD%BF%E7%94%A8%0A%E9%80%9A%E5%B8%B8%E6%83%85%E5%86%B5%E4%B8%8B%EF%BC%8C%E6%88%91%E4%BB%AC%E4%BC%9A%E6%8A%8A%E5%90%8E%E7%AB%AF%E8%BF%94%E5%9B%9E%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F%E5%8D%95%E7%8B%AC%E6%94%BE%E5%85%A5%E4%B8%80%E4%B8%AA%20interface%20%E9%87%8C%EF%BC%9A%0A%60%60%60ts%0A%2F%2F%20%E8%AF%B7%E6%B1%82%E6%8E%A5%E5%8F%A3%E6%95%B0%E6%8D%AE%0Aexport%20interface%20ResponseData%3CT%20%3D%20any%3E%20%7B%0A%20%20%2F**%0A%20%20%20*%20%E7%8A%B6%E6%80%81%E7%A0%81%0A%20%20%20*%20%40type%20%7B%20number%20%7D%0A%20%20%20*%2F%0A%20%20code%3A%20number%3B%0A%0A%20%20%2F**%0A%20%20%20*%20%E6%95%B0%E6%8D%AE%0A%20%20%20*%20%40type%20%7B%20T%20%7D%0A%20%20%20*%2F%0A%20%20result%3A%20T%3B%0A%0A%20%20%2F**%0A%20%20%20*%20%E6%B6%88%E6%81%AF%0A%20%20%20*%20%40type%20%7B%20string%20%7D%0A%20%20%20*%2F%0A%20%20message%3A%20string%3B%0A%7D%0A%60%60%60%0A%0A%E5%BD%93%E6%88%91%E4%BB%AC%E6%8A%8A%20API%20%E5%8D%95%E7%8B%AC%E6%8A%BD%E7%A6%BB%E6%88%90%E5%8D%95%E4%B8%AA%E6%A8%A1%E5%9D%97%E6%97%B6%EF%BC%9A%0A%60%60%60ts%0A%2F%2F%20%E5%9C%A8%20axios.ts%20%E6%96%87%E4%BB%B6%E4%B8%AD%E5%AF%B9%20axios%20%E8%BF%9B%E8%A1%8C%E4%BA%86%E5%A4%84%E7%90%86%EF%BC%8C%E4%BE%8B%E5%A6%82%E6%B7%BB%E5%8A%A0%E9%80%9A%E7%94%A8%E9%85%8D%E7%BD%AE%E3%80%81%E6%8B%A6%E6%88%AA%E5%99%A8%E7%AD%89%0Aimport%20Ax%20from%20'.%2Faxios'%3B%0A%0Aimport%20%7B%20ResponseData%20%7D%20from%20'.%2Finterface.ts'%3B%0A%0Aexport%20function%20getUser%3CT%3E()%20%7B%0A%20%20return%20Ax.get%3CResponseData%3CT%3E%3E('%2Fsomepath')%0A%20%20%20%20.then(res%20%3D%3E%20res.data)%0A%20%20%20%20.catch(err%20%3D%3E%20console.error(err))%3B%0A%7D%0A%60%60%60%0A%0A%E6%8E%A5%E7%9D%80%E6%88%91%E4%BB%AC%E5%86%99%E5%85%A5%E8%BF%94%E5%9B%9E%E7%9A%84%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B%20User%EF%BC%8C%E8%BF%99%E5%8F%AF%E4%BB%A5%E8%AE%A9%20TypeScript%20%E9%A1%BA%E5%88%A9%E6%8E%A8%E6%96%AD%E5%87%BA%E6%88%91%E4%BB%AC%E6%83%B3%E8%A6%81%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%9A%0A%60%60%60ts%0Ainterface%20User%20%7B%0A%20%20name%3A%20string%3B%0A%20%20age%3A%20number%3B%0A%7D%0A%0Aasync%20function%20test()%20%7B%0A%20%20%2F%2F%20user%20%E8%A2%AB%E6%8E%A8%E6%96%AD%E5%87%BA%E4%B8%BA%0A%20%20%2F%2F%20%7B%0A%20%20%2F%2F%20%20code%3A%20number%2C%0A%20%20%2F%2F%20%20result%3A%20%7B%20name%3A%20string%2C%20age%3A%20number%20%7D%2C%0A%20%20%2F%2F%20%20message%3A%20string%0A%20%20%2F%2F%20%7D%0A%20%20const%20user%20%3D%20await%20getUser%3CUser%3E()%3B%0A%7D%0A%60%60%60%0A%0A%23%23%20%E7%B1%BB%E5%9E%8B%E6%8E%A8%E6%96%AD%0A%0A%23%23%23%23%20%E5%AE%9A%E4%B9%89%E5%8F%98%E9%87%8F%0A%60%60%60ts%0Alet%20foo%20%3D%20123%3B%20%2F%2F%20foo%20%E6%98%AF%20'number'%0Alet%20bar%20%3D%20'hello'%3B%20%2F%2F%20bar%20%E6%98%AF%20'string'%0A%0Afoo%20%3D%20bar%3B%20%2F%2F%20Error%3A%20%E4%B8%8D%E8%83%BD%E5%B0%86%20'string'%20%E8%B5%8B%E5%80%BC%E7%BB%99%20%60number%60%0A%60%60%60%0A%23%23%23%23%20%E5%87%BD%E6%95%B0%E8%BF%94%E5%9B%9E%E7%B1%BB%E5%9E%8B%0A%60%60%60ts%0Afunction%20add(a%3A%20number%2C%20b%3A%20number)%20%7B%0A%20%20return%20a%20%2B%20b%3B%0A%7D%0A%60%60%60%0A%23%23%23%23%20%E8%B5%8B%E5%80%BC%0A%60%60%60ts%0Atype%20Adder%20%3D%20(a%3A%20number%2C%20b%3A%20number)%20%3D%3E%20number%3B%0Alet%20foo%3A%20Adder%20%3D%20(a%2C%20b)%20%3D%3E%20a%20%2B%20b%3B%0A%60%60%60%0A%23%23%23%23%20%E7%BB%93%E6%9E%84%E5%8C%96%0A%60%60%60ts%0Aconst%20foo%20%3D%20%7B%0A%20%20a%3A%20123%2C%0A%20%20b%3A%20456%0A%7D%3B%0A%0Afoo.a%20%3D%20'hello'%3B%20%2F%2F%20Error%EF%BC%9A%E4%B8%8D%E8%83%BD%E6%8A%8A%20'string'%20%E7%B1%BB%E5%9E%8B%E8%B5%8B%E5%80%BC%E7%BB%99%20'number'%20%E7%B1%BB%E5%9E%8B%0A%60%60%60%0A%23%23%23%23%20%E8%A7%A3%E6%9E%84%0A%60%60%60ts%0Aconst%20foo%20%3D%20%7B%0A%20%20a%3A%20123%2C%0A%20%20b%3A%20456%0A%7D%3B%0Alet%20%7B%20a%20%7D%20%3D%20foo%3B%0A%0Aa%20%3D%20'hello'%3B%20%2F%2F%20Error%EF%BC%9A%E4%B8%8D%E8%83%BD%E6%8A%8A%20'string'%20%E7%B1%BB%E5%9E%8B%E8%B5%8B%E5%80%BC%E7%BB%99%20'number'%20%E7%B1%BB%E5%9E%8B%0A%60%60%60%0A%0A%23%23%23%23%20%E8%AD%A6%E5%91%8A%0A%60%60%60ts%0A%2F%2F%E4%BE%8B%E5%AD%901%EF%BC%9A%E5%B0%8F%E5%BF%83%E4%BD%BF%E7%94%A8%E5%8F%82%E6%95%B0%0Aconst%20foo%20%3D%20(a%2C%20b)%20%3D%3E%20%7B%0A%20%20%2F*%20do%20something%20*%2F%0A%7D%3B%0A%0A%0A%2F%2F%E4%BE%8B%E5%AD%902%EF%BC%9A%E5%B0%8F%E5%BF%83%E4%BD%BF%E7%94%A8%E8%BF%94%E5%9B%9E%E5%80%BC%0Afunction%20foo(a%3A%20number%2C%20b%3A%20number)%20%7B%0A%20%20return%20a%20%2B%20addOne(b)%3B%0A%7D%0A%2F%2F%20%E4%B8%80%E4%BA%9B%E4%BD%BF%E7%94%A8%20JavaScript%20%E5%BA%93%E7%9A%84%E7%89%B9%E6%AE%8A%E5%87%BD%E6%95%B0%0Afunction%20addOne(a)%20%7B%0A%20%20return%20a%20%2B%201%3B%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20noImplicitAny%0A%E9%80%89%E9%A1%B9%20noImplicitAny%20%E7%94%A8%E6%9D%A5%E5%91%8A%E8%AF%89%E7%BC%96%E8%AF%91%E5%99%A8%EF%BC%8C%E5%BD%93%E6%97%A0%E6%B3%95%E6%8E%A8%E6%96%AD%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E6%97%B6%E5%8F%91%E5%87%BA%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF%EF%BC%88%E6%88%96%E8%80%85%E5%8F%AA%E8%83%BD%E6%8E%A8%E6%96%AD%E4%B8%BA%E4%B8%80%E4%B8%AA%E9%9A%90%E5%BC%8F%E7%9A%84%20any%20%E7%B1%BB%E5%9E%8B%EF%BC%89%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%EF%BC%9A%0A1%E3%80%81%E9%80%9A%E8%BF%87%E6%98%BE%E5%BC%8F%E6%B7%BB%E5%8A%A0%20%3Aany%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%EF%BC%8C%E6%9D%A5%E8%AE%A9%E5%AE%83%E6%88%90%E4%B8%BA%E4%B8%80%E4%B8%AA%20any%20%E7%B1%BB%E5%9E%8B%EF%BC%9B%0A2%E3%80%81%E9%80%9A%E8%BF%87%E4%B8%80%E4%BA%9B%E6%9B%B4%E6%AD%A3%E7%A1%AE%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%E6%9D%A5%E5%B8%AE%E5%8A%A9%20TypeScript%20%E6%8E%A8%E6%96%AD%E7%B1%BB%E5%9E%8B%E3%80%82%0A%0A%23%23%20%E7%B1%BB%E5%9E%8B%E5%85%BC%E5%AE%B9%E6%80%A7%0A%E7%B1%BB%E5%9E%8B%E5%85%BC%E5%AE%B9%E6%80%A7%E7%94%A8%E4%BA%8E%E7%A1%AE%E5%AE%9A%E4%B8%80%E4%B8%AA%E7%B1%BB%E5%9E%8B%E6%98%AF%E5%90%A6%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%E5%85%B6%E4%BB%96%E7%B1%BB%E5%9E%8B%E3%80%82%0A%E5%A6%82%20string%20%E7%B1%BB%E5%9E%8B%E4%B8%8E%20number%20%E7%B1%BB%E5%9E%8B%E4%B8%8D%E5%85%BC%E5%AE%B9%EF%BC%9A%0A%60%60%60ts%0Alet%20str%3A%20string%20%3D%20'Hello'%3B%0Alet%20num%3A%20number%20%3D%20123%3B%0A%0Astr%20%3D%20num%3B%20%2F%2F%20Error%3A%20'number'%20%E4%B8%8D%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%20'string'%0Anum%20%3D%20str%3B%20%2F%2F%20Error%3A%20'string'%20%E4%B8%8D%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%20'number'%0A%60%60%60%0A%0A%23%23%23%23%20%E5%AE%89%E5%85%A8%E6%80%A7%0ATypeScript%20%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F%E8%AE%BE%E8%AE%A1%E6%AF%94%E8%BE%83%E6%96%B9%E4%BE%BF%EF%BC%8C%E5%AE%83%E5%85%81%E8%AE%B8%E4%BD%A0%E6%9C%89%E4%B8%80%E4%BA%9B%E4%B8%8D%E6%AD%A3%E7%A1%AE%E7%9A%84%E8%A1%8C%E4%B8%BA%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%9A%E4%BB%BB%E4%BD%95%E7%B1%BB%E5%9E%8B%E9%83%BD%E8%83%BD%E8%A2%AB%E8%B5%8B%E5%80%BC%E7%BB%99%20any%EF%BC%8C%E8%BF%99%E6%84%8F%E5%91%B3%E7%9D%80%E5%91%8A%E8%AF%89%E7%BC%96%E8%AF%91%E5%99%A8%E4%BD%A0%E5%8F%AF%E4%BB%A5%E5%81%9A%E4%BB%BB%E4%BD%95%E4%BD%A0%E6%83%B3%E5%81%9A%E7%9A%84%E4%BA%8B%E6%83%85%EF%BC%9A%0A%60%60%60%0Alet%20foo%3A%20any%20%3D%20123%3B%0Afoo%20%3D%20'hello'%3B%0A%0Afoo.toPrecision(3)%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E7%BB%93%E6%9E%84%E5%8C%96%0ATypeScript%20%E5%AF%B9%E8%B1%A1%E6%98%AF%E4%B8%80%E7%A7%8D%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%EF%BC%8C%E8%BF%99%E6%84%8F%E5%91%B3%E7%9D%80%E5%8F%AA%E8%A6%81%E7%BB%93%E6%9E%84%E5%8C%B9%E9%85%8D%EF%BC%8C%E5%90%8D%E7%A7%B0%E4%B9%9F%E5%B0%B1%E6%97%A0%E5%85%B3%E7%B4%A7%E8%A6%81%E4%BA%86%EF%BC%9A%0A%60%60%60ts%0Ainterface%20Point%20%7B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%7D%0A%0Aclass%20Point2D%20%7B%0A%20%20constructor(public%20x%3A%20number%2C%20public%20y%3A%20number)%20%7B%7D%0A%7D%0A%0Alet%20p%3A%20Point%3B%0A%0A%2F%2F%20ok%2C%20%E5%9B%A0%E4%B8%BA%E6%98%AF%E7%BB%93%E6%9E%84%E5%8C%96%E7%9A%84%E7%B1%BB%E5%9E%8B%0Ap%20%3D%20new%20Point2D(1%2C%202)%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E5%8F%98%E4%BD%93%0A%E5%AF%B9%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%B1%BB%E5%9E%8B%20Base%20%E5%92%8C%20Child%20%E6%9D%A5%E8%AF%B4%EF%BC%8C%E5%A6%82%E6%9E%9C%20Child%20%E6%98%AF%20Base%20%E7%9A%84%E5%AD%90%E7%B1%BB%EF%BC%8CChild%20%E7%9A%84%E5%AE%9E%E4%BE%8B%E8%83%BD%E8%A2%AB%E8%B5%8B%E5%80%BC%E7%BB%99%20Base%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%8F%98%E9%87%8F%E3%80%82%0A%0A%E5%9C%A8%E7%94%B1%20Base%20%E5%92%8C%20Child%20%E7%BB%84%E5%90%88%E7%9A%84%E5%A4%8D%E6%9D%82%E7%B1%BB%E5%9E%8B%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%85%BC%E5%AE%B9%E6%80%A7%E4%B8%AD%EF%BC%8C%E5%AE%83%E5%8F%96%E5%86%B3%E4%BA%8E%E7%9B%B8%E5%90%8C%E5%9C%BA%E6%99%AF%E4%B8%8B%E7%9A%84%20Base%20%E4%B8%8E%20Child%20%E7%9A%84%E5%8F%98%E4%BD%93%EF%BC%9A%0A%0A*%20%E5%8D%8F%E5%8F%98%EF%BC%88Covariant%EF%BC%89%EF%BC%9A%E5%8F%AA%E5%9C%A8%E5%90%8C%E4%B8%80%E4%B8%AA%E6%96%B9%E5%90%91%EF%BC%9B%0A*%20%E9%80%86%E5%8F%98%EF%BC%88Contravariant%EF%BC%89%EF%BC%9A%E5%8F%AA%E5%9C%A8%E7%9B%B8%E5%8F%8D%E7%9A%84%E6%96%B9%E5%90%91%EF%BC%9B%0A*%20%E5%8F%8C%E5%90%91%E5%8D%8F%E5%8F%98%EF%BC%88Bivariant%EF%BC%89%EF%BC%9A%E5%8C%85%E6%8B%AC%E5%90%8C%E4%B8%80%E4%B8%AA%E6%96%B9%E5%90%91%E5%92%8C%E4%B8%8D%E5%90%8C%E6%96%B9%E5%90%91%EF%BC%9B%0A*%20%E4%B8%8D%E5%8F%98%EF%BC%88Invariant%EF%BC%89%EF%BC%9A%E5%A6%82%E6%9E%9C%E7%B1%BB%E5%9E%8B%E4%B8%8D%E5%AE%8C%E5%85%A8%E7%9B%B8%E5%90%8C%EF%BC%8C%E5%88%99%E5%AE%83%E4%BB%AC%E6%98%AF%E4%B8%8D%E5%85%BC%E5%AE%B9%E7%9A%84%E3%80%82%0A%0A*%E5%AF%B9%E4%BA%8E%E5%AD%98%E5%9C%A8%E5%AE%8C%E5%85%A8%E5%8F%AF%E5%8F%98%E6%95%B0%E6%8D%AE%E7%9A%84%E5%81%A5%E5%85%A8%E7%9A%84%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F%EF%BC%88%E5%A6%82%20JavaScript%EF%BC%89%EF%BC%8CInvariant%20%E6%98%AF%E4%B8%80%E4%B8%AA%E5%94%AF%E4%B8%80%E7%9A%84%E6%9C%89%E6%95%88%E5%8F%AF%E9%80%89%E5%B1%9E%E6%80%A7%EF%BC%8C%E4%BD%86%E6%98%AF%E5%A6%82%E6%88%91%E4%BB%AC%E8%AF%B4%E8%AE%A8%E8%AE%BA%E7%9A%84%EF%BC%8C%E4%BE%BF%E5%88%A9%E6%80%A7%E8%BF%AB%E4%BD%BF%E6%88%91%E4%BB%AC%E4%BD%9C%E5%87%BA%E4%B8%80%E4%BA%9B%E4%B8%8D%E6%98%AF%E5%BE%88%E5%AE%89%E5%85%A8%E7%9A%84%E9%80%89%E6%8B%A9%E3%80%82*%0A%0A%23%23%23%23%20%E5%87%BD%E6%95%B0%0A%E5%BD%93%E4%BD%A0%E5%9C%A8%E6%AF%94%E8%BE%83%E4%B8%A4%E4%B8%AA%E5%87%BD%E6%95%B0%E6%97%B6%EF%BC%8C%E8%BF%99%E6%9C%89%E4%B8%80%E4%BA%9B%E4%BD%A0%E9%9C%80%E8%A6%81%E8%80%83%E8%99%91%E5%88%B0%E7%9A%84%E4%BA%8B%E6%83%85%0A%23%23%23%23%23%20%E8%BF%94%E5%9B%9E%E7%B1%BB%E5%9E%8B%0A%E5%8D%8F%E5%8F%98%EF%BC%88Covariant%EF%BC%89%EF%BC%9A%E8%BF%94%E5%9B%9E%E7%B1%BB%E5%9E%8B%E5%BF%85%E9%A1%BB%E5%8C%85%E5%90%AB%E8%B6%B3%E5%A4%9F%E7%9A%84%E6%95%B0%E6%8D%AE%E3%80%82%0A%60%60%60ts%0Ainterface%20Point2D%20%7B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%7D%0Ainterface%20Point3D%20%7B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%20%20z%3A%20number%3B%0A%7D%0A%0Alet%20iMakePoint2D%20%3D%20()%3A%20Point2D%20%3D%3E%20(%7B%20x%3A%200%2C%20y%3A%200%20%7D)%3B%0Alet%20iMakePoint3D%20%3D%20()%3A%20Point3D%20%3D%3E%20(%7B%20x%3A%200%2C%20y%3A%200%2C%20z%3A%200%20%7D)%3B%0A%0AiMakePoint2D%20%3D%20iMakePoint3D%3B%0AiMakePoint3D%20%3D%20iMakePoint2D%3B%20%2F%2F%20ERROR%3A%20Point2D%20%E4%B8%8D%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%20Point3D%0A%60%60%60%0A%0A%23%23%23%23%23%20%E5%8F%82%E6%95%B0%E6%95%B0%E9%87%8F%0A%E6%9B%B4%E5%B0%91%E7%9A%84%E5%8F%82%E6%95%B0%E6%95%B0%E9%87%8F%E6%98%AF%E5%A5%BD%E7%9A%84%EF%BC%88%E5%A6%82%EF%BC%9A%E5%87%BD%E6%95%B0%E8%83%BD%E5%A4%9F%E9%80%89%E6%8B%A9%E6%80%A7%E7%9A%84%E5%BF%BD%E7%95%A5%E4%B8%80%E4%BA%9B%E5%A4%9A%E4%BD%99%E7%9A%84%E5%8F%82%E6%95%B0%EF%BC%89%EF%BC%8C%E4%BD%86%E6%98%AF%E4%BD%A0%E5%BE%97%E4%BF%9D%E8%AF%81%E6%9C%89%E8%B6%B3%E5%A4%9F%E7%9A%84%E5%8F%82%E6%95%B0%E8%A2%AB%E4%BD%BF%E7%94%A8%E4%BA%86%EF%BC%9A%0A%60%60%60ts%0Aconst%20iTakeSomethingAndPassItAnErr%20%3D%20(x%3A%20(err%3A%20Error%2C%20data%3A%20any)%20%3D%3E%20void)%20%3D%3E%20%7B%0A%20%20%2F*%20%E5%81%9A%E4%B8%80%E4%BA%9B%E5%85%B6%E4%BB%96%E7%9A%84%20*%2F%0A%7D%3B%0A%0AiTakeSomethingAndPassItAnErr(()%20%3D%3E%20null)%3B%20%2F%2F%20ok%0AiTakeSomethingAndPassItAnErr(err%20%3D%3E%20null)%3B%20%2F%2F%20ok%0AiTakeSomethingAndPassItAnErr((err%2C%20data)%20%3D%3E%20null)%3B%20%2F%2F%20ok%0A%0A%2F%2F%20Error%3A%20%E5%8F%82%E6%95%B0%E7%B1%BB%E5%9E%8B%20%60(err%3A%20any%2C%20data%3A%20any%2C%20more%3A%20any)%20%3D%3E%20null%60%20%E4%B8%8D%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%E5%8F%82%E6%95%B0%E7%B1%BB%E5%9E%8B%20%60(err%3A%20Error%2C%20data%3A%20any)%20%3D%3E%20void%60%0AiTakeSomethingAndPassItAnErr((err%2C%20data%2C%20more)%20%3D%3E%20null)%3B%0A%60%60%60%0A%0A%23%23%23%23%23%20%E5%8F%AF%E9%80%89%E7%9A%84%E5%92%8C%20rest%20%E5%8F%82%E6%95%B0%0A%E5%8F%AF%E9%80%89%E7%9A%84%EF%BC%88%E9%A2%84%E5%85%88%E7%A1%AE%E5%AE%9A%E7%9A%84%EF%BC%89%E5%92%8C%20Rest%20%E5%8F%82%E6%95%B0%EF%BC%88%E4%BB%BB%E4%BD%95%E6%95%B0%E9%87%8F%E7%9A%84%E5%8F%82%E6%95%B0%EF%BC%89%E9%83%BD%E6%98%AF%E5%85%BC%E5%AE%B9%E7%9A%84%EF%BC%9A%0A%60%60%60ts%0Alet%20foo%20%3D%20(x%3A%20number%2C%20y%3A%20number)%20%3D%3E%20%7B%7D%3B%0Alet%20bar%20%3D%20(x%3F%3A%20number%2C%20y%3F%3A%20number)%20%3D%3E%20%7B%7D%3B%0Alet%20bas%20%3D%20(...args%3A%20number%5B%5D)%20%3D%3E%20%7B%7D%3B%0A%0Afoo%20%3D%20bar%20%3D%20bas%3B%0Abas%20%3D%20bar%20%3D%20foo%3B%0A%0A%2F%2F%E5%8F%AF%E9%80%89%E7%9A%84%EF%BC%88%E4%B8%8A%E4%BE%8B%E5%AD%90%E4%B8%AD%E7%9A%84%20bar%EF%BC%89%E4%B8%8E%E4%B8%8D%E5%8F%AF%E9%80%89%E7%9A%84%EF%BC%88%E4%B8%8A%E4%BE%8B%E5%AD%90%E4%B8%AD%E7%9A%84%20foo%EF%BC%89%E4%BB%85%E5%9C%A8%E9%80%89%E9%A1%B9%E4%B8%BA%20strictNullChecks%20%E4%B8%BA%20false%20%E6%97%B6%E5%85%BC%E5%AE%B9%E3%80%82%0A%60%60%60%0A%0A%23%23%23%23%23%20%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0%E7%B1%BB%E5%9E%8B%0A%E5%8F%8C%E5%90%91%E5%8D%8F%E5%8F%98%EF%BC%88Bivariant%EF%BC%89%EF%BC%9A%E6%97%A8%E5%9C%A8%E6%94%AF%E6%8C%81%E5%B8%B8%E8%A7%81%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%A4%84%E7%90%86%E6%96%B9%E6%A1%88%E3%80%82%0A%60%60%60ts%0Ainterface%20Point2D%20%7B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%7D%0Ainterface%20Point3D%20%7B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%20%20z%3A%20number%3B%0A%7D%0A%0Alet%20iTakePoint2D%20%3D%20(point%3A%20Point2D)%20%3D%3E%20%7B%7D%3B%0Alet%20iTakePoint3D%20%3D%20(point%3A%20Point3D)%20%3D%3E%20%7B%7D%3B%0A%0AiTakePoint3D%20%3D%20iTakePoint2D%3B%20%2F%2F%20ok%2C%20%E8%BF%99%E6%98%AF%E5%90%88%E7%90%86%E7%9A%84%0AiTakePoint2D%20%3D%20iTakePoint3D%3B%20%2F%2F%20ok%EF%BC%8C%E4%B8%BA%E4%BB%80%E4%B9%88%EF%BC%9F%0A%60%60%60%0A%0A%23%23%23%23%20%E6%9E%9A%E4%B8%BE%0A%E6%9E%9A%E4%B8%BE%E4%B8%8E%E6%95%B0%E5%AD%97%E7%B1%BB%E5%9E%8B%E7%9B%B8%E4%BA%92%E5%85%BC%E5%AE%B9%0A%60%60%60ts%0Aenum%20Status%20%7B%0A%20%20Ready%2C%0A%20%20Waiting%0A%7D%0A%0Alet%20status%20%3D%20Status.Ready%3B%0Alet%20num%20%3D%200%3B%0A%0Astatus%20%3D%20num%3B%0Anum%20%3D%20status%3B%0A%60%60%60%0A%0A%E6%9D%A5%E8%87%AA%E4%BA%8E%E4%B8%8D%E5%90%8C%E6%9E%9A%E4%B8%BE%E7%9A%84%E6%9E%9A%E4%B8%BE%E5%8F%98%E9%87%8F%EF%BC%8C%E8%A2%AB%E8%AE%A4%E4%B8%BA%E6%98%AF%E4%B8%8D%E5%85%BC%E5%AE%B9%E7%9A%84%EF%BC%9A%0A%60%60%60ts%0Aenum%20Status%20%7B%0A%20%20Ready%2C%0A%20%20Waiting%0A%7D%0Aenum%20Color%20%7B%0A%20%20Red%2C%0A%20%20Blue%2C%0A%20%20Green%0A%7D%0A%0Alet%20status%20%3D%20Status.Ready%3B%0Alet%20color%20%3D%20Color.Red%3B%0A%0Astatus%20%3D%20color%3B%20%2F%2F%20Error%0A%60%60%60%0A%0A%23%23%23%23%20%E7%B1%BB%0A%E4%BB%85%E4%BB%85%E5%8F%AA%E6%9C%89%E5%AE%9E%E4%BE%8B%E6%88%90%E5%91%98%E5%92%8C%E6%96%B9%E6%B3%95%E4%BC%9A%E7%9B%B8%E6%AF%94%E8%BE%83%EF%BC%8C%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E5%92%8C%E9%9D%99%E6%80%81%E6%88%90%E5%91%98%E4%B8%8D%E4%BC%9A%E8%A2%AB%E6%A3%80%E6%9F%A5%E3%80%82%0A%60%60%60ts%0Aclass%20Animal%20%7B%0A%20%20feet%3A%20number%3B%0A%20%20constructor(name%3A%20string%2C%20numFeet%3A%20number)%20%7B%7D%0A%7D%0A%0Aclass%20Size%20%7B%0A%20%20feet%3A%20number%3B%0A%20%20constructor(meters%3A%20number)%20%7B%7D%0A%7D%0A%0Alet%20a%3A%20Animal%3B%0Alet%20s%3A%20Size%3B%0A%0Aa%20%3D%20s%3B%20%2F%2F%20OK%0As%20%3D%20a%3B%20%2F%2F%20OK%0A%60%60%60%0A%0A%E7%A7%81%E6%9C%89%E7%9A%84%E5%92%8C%E5%8F%97%E4%BF%9D%E6%8A%A4%E7%9A%84%E6%88%90%E5%91%98%E5%BF%85%E9%A1%BB%E6%9D%A5%E8%87%AA%E4%BA%8E%E7%9B%B8%E5%90%8C%E7%9A%84%E7%B1%BB%E3%80%82%0A%60%60%60ts%0Aclass%20Animal%20%7B%0A%20%20protected%20feet%3A%20number%3B%0A%7D%0Aclass%20Cat%20extends%20Animal%20%7B%7D%0A%0Alet%20animal%3A%20Animal%3B%0Alet%20cat%3A%20Cat%3B%0A%0Aanimal%20%3D%20cat%3B%20%2F%2F%20ok%0Acat%20%3D%20animal%3B%20%2F%2F%20ok%0A%0Aclass%20Size%20%7B%0A%20%20protected%20feet%3A%20number%3B%0A%7D%0A%0Alet%20size%3A%20Size%3B%0A%0Aanimal%20%3D%20size%3B%20%2F%2F%20ERROR%0Asize%20%3D%20animal%3B%20%2F%2F%20ERROR%0A%60%60%60%0A%0A%23%23%23%23%20%E6%B3%9B%E5%9E%8B%0A%0ATypeScript%20%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F%E5%9F%BA%E4%BA%8E%E5%8F%98%E9%87%8F%E7%9A%84%E7%BB%93%E6%9E%84%EF%BC%8C%E4%BB%85%E5%BD%93%E7%B1%BB%E5%9E%8B%E5%8F%82%E6%95%B0%E5%9C%A8%E8%A2%AB%E4%B8%80%E4%B8%AA%E6%88%90%E5%91%98%E4%BD%BF%E7%94%A8%E6%97%B6%EF%BC%8C%E6%89%8D%E4%BC%9A%E5%BD%B1%E5%93%8D%E5%85%BC%E5%AE%B9%E6%80%A7%E3%80%82%0A%60%60%60%0A%2F%2F%E5%BD%93%20T%20%E6%B2%A1%E6%9C%89%E8%A2%AB%E6%88%90%E5%91%98%E4%BD%BF%E7%94%A8%E6%97%B6%EF%BC%8C%E5%AE%83%E5%AF%B9%E5%85%BC%E5%AE%B9%E6%80%A7%E6%B2%A1%E6%9C%89%E5%BD%B1%E5%93%8D%EF%BC%9A%0Ainterface%20Empty%3CT%3E%20%7B%7D%0A%0Alet%20x%3A%20Empty%3Cnumber%3E%3B%0Alet%20y%3A%20Empty%3Cstring%3E%3B%0A%0Ax%20%3D%20y%3B%20%2F%2F%20ok%0A%0A%2F%2F%E5%BD%93%20T%20%E8%A2%AB%E6%88%90%E5%91%98%E4%BD%BF%E7%94%A8%E6%97%B6%EF%BC%8C%E5%AE%83%E5%B0%86%E5%9C%A8%E5%AE%9E%E4%BE%8B%E5%8C%96%E6%B3%9B%E5%9E%8B%E5%90%8E%E5%BD%B1%E5%93%8D%E5%85%BC%E5%AE%B9%E6%80%A7%EF%BC%9A%0A%2F%2F%E5%A6%82%E6%9E%9C%E5%B0%9A%E6%9C%AA%E5%AE%9E%E4%BE%8B%E5%8C%96%E6%B3%9B%E5%9E%8B%E5%8F%82%E6%95%B0%EF%BC%8C%E5%88%99%E5%9C%A8%E6%A3%80%E6%9F%A5%E5%85%BC%E5%AE%B9%E6%80%A7%E4%B9%8B%E5%89%8D%E5%B0%86%E5%85%B6%E6%9B%BF%E6%8D%A2%E4%B8%BA%20any%EF%BC%9A%0Ainterface%20Empty%3CT%3E%20%7B%0A%20%20data%3A%20T%3B%0A%7D%0A%0Alet%20x%3A%20Empty%3Cnumber%3E%3B%0Alet%20y%3A%20Empty%3Cstring%3E%3B%0A%0Ax%20%3D%20y%3B%20%2F%2F%20Error%0A%60%60%60%0A%0A%23%23%23%23%20%E8%84%9A%E6%B3%A8%EF%BC%9A%E4%B8%8D%E5%8F%98%E6%80%A7%EF%BC%88Invariance%EF%BC%89%0A%60%60%60ts%0A%E6%88%91%E4%BB%AC%E8%AF%B4%E8%BF%87%EF%BC%8C%E4%B8%8D%E5%8F%98%E6%80%A7%E5%8F%AF%E8%83%BD%E6%98%AF%E5%94%AF%E4%B8%80%E4%B8%80%E4%B8%AA%E5%90%AC%E8%B5%B7%E6%9D%A5%E5%90%88%E7%90%86%E7%9A%84%E9%80%89%E9%A1%B9%EF%BC%8C%E8%BF%99%E9%87%8C%E6%9C%89%E4%B8%80%E4%B8%AA%E5%85%B3%E4%BA%8E%20contra%20%E5%92%8C%20co%20%E7%9A%84%E5%8F%98%E4%BD%93%EF%BC%8C%E8%A2%AB%E8%AE%A4%E4%B8%BA%E5%AF%B9%E6%95%B0%E7%BB%84%E6%98%AF%E4%B8%8D%E5%AE%89%E5%85%A8%E7%9A%84%E3%80%82%0Aclass%20Animal%20%7B%0A%20%20constructor(public%20name%3A%20string)%20%7B%7D%0A%7D%0Aclass%20Cat%20extends%20Animal%20%7B%0A%20%20meow()%20%7B%0A%20%20%20%20console.log('cat')%3B%0A%20%20%7D%0A%7D%0A%0Alet%20animal%20%3D%20new%20Animal('animal')%3B%0Alet%20cat%20%3D%20new%20Cat('cat')%3B%0A%0A%2F%2F%20%E5%A4%9A%E6%80%81%0A%2F%2F%20Animal%20%3C%3D%20Cat%0A%0Aanimal%20%3D%20cat%3B%20%2F%2F%20ok%0Acat%20%3D%20animal%3B%20%2F%2F%20ERROR%3A%20cat%20%E7%BB%A7%E6%89%BF%E4%BA%8E%20animal%0A%0A%2F%2F%20%E6%BC%94%E7%A4%BA%E6%AF%8F%E4%B8%AA%E6%95%B0%E7%BB%84%E5%BD%A2%E5%BC%8F%0Alet%20animalArr%3A%20Animal%5B%5D%20%3D%20%5Banimal%5D%3B%0Alet%20catArr%3A%20Cat%5B%5D%20%3D%20%5Bcat%5D%3B%0A%0A%2F%2F%20%E6%98%8E%E6%98%BE%E7%9A%84%E5%9D%8F%E5%A4%84%EF%BC%8C%E9%80%86%E5%8F%98%0A%2F%2F%20Animal%20%3C%3D%20Cat%0A%2F%2F%20Animal%5B%5D%20%3E%3D%20Cat%5B%5D%0AcatArr%20%3D%20animalArr%3B%20%2F%2F%20ok%2C%20%E5%A6%82%E6%9C%89%E6%9C%89%E9%80%86%E5%8F%98%0AcatArr%5B0%5D.meow()%3B%20%2F%2F%20%E5%85%81%E8%AE%B8%EF%BC%8C%E4%BD%86%E6%98%AF%E4%BC%9A%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E6%8A%A5%E9%94%99%0A%0A%2F%2F%20%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AA%E5%9D%8F%E5%A4%84%EF%BC%8C%E5%8D%8F%E5%8F%98%0A%2F%2F%20Animal%20%3C%3D%20Cat%0A%2F%2F%20Animal%5B%5D%20%3C%3D%20Cat%5B%5D%0AanimalArr%20%3D%20catArr%3B%20%2F%2F%20ok%EF%BC%8C%E5%8D%8F%E5%8F%98%0A%0AanimalArr.push(new%20Animal('another%20animal'))%3B%20%2F%2F%20%E4%BB%85%E4%BB%85%E6%98%AF%20push%20%E4%B8%80%E4%B8%AA%20animal%20%E8%87%B3%20carArr%20%E9%87%8C%0AcatArr.forEach(c%20%3D%3E%20c.meow())%3B%20%2F%2F%20%E5%85%81%E8%AE%B8%EF%BC%8C%E4%BD%86%E6%98%AF%E4%BC%9A%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E6%8A%A5%E9%94%99%E3%80%82%0A%60%60%60%0A%0A%23%23%20Never%0Anever%20%E7%B1%BB%E5%9E%8B%E6%98%AF%20TypeScript%20%E4%B8%AD%E7%9A%84%E5%BA%95%E5%B1%82%E7%B1%BB%E5%9E%8B%E3%80%82%E5%AE%83%E8%87%AA%E7%84%B6%E8%A2%AB%E5%88%86%E9%85%8D%E7%9A%84%E4%B8%80%E4%BA%9B%E4%BE%8B%E5%AD%90%EF%BC%9A%0A%0A*%20%E4%B8%80%E4%B8%AA%E4%BB%8E%E6%9D%A5%E4%B8%8D%E4%BC%9A%E6%9C%89%E8%BF%94%E5%9B%9E%E5%80%BC%E7%9A%84%E5%87%BD%E6%95%B0%EF%BC%88%E5%A6%82%EF%BC%9A%E5%A6%82%E6%9E%9C%E5%87%BD%E6%95%B0%E5%86%85%E5%90%AB%E6%9C%89%20while(true)%20%7B%7D%EF%BC%89%EF%BC%9B%0A*%20%E4%B8%80%E4%B8%AA%E6%80%BB%E6%98%AF%E4%BC%9A%E6%8A%9B%E5%87%BA%E9%94%99%E8%AF%AF%E7%9A%84%E5%87%BD%E6%95%B0%EF%BC%88%E5%A6%82%EF%BC%9Afunction%20foo()%20%7B%20throw%20new%20Error('Not%20Implemented')%20%7D%EF%BC%8Cfoo%20%E7%9A%84%E8%BF%94%E5%9B%9E%E7%B1%BB%E5%9E%8B%E6%98%AF%20never%EF%BC%89%EF%BC%9B%0A%0A%E4%BD%A0%E4%B9%9F%E5%8F%AF%E4%BB%A5%E5%B0%86%E5%AE%83%E7%94%A8%E5%81%9A%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%EF%BC%9A%0A%60%60%60ts%0Alet%20foo%3A%20never%3B%20%2F%2F%20ok%0A%60%60%60%0A%E4%BD%86%E6%98%AF%EF%BC%8Cnever%20%E7%B1%BB%E5%9E%8B%E4%BB%85%E8%83%BD%E8%A2%AB%E8%B5%8B%E5%80%BC%E7%BB%99%E5%8F%A6%E5%A4%96%E4%B8%80%E4%B8%AA%20never%EF%BC%9A%0A%60%60%60ts%0Alet%20foo%3A%20never%20%3D%20123%3B%20%2F%2F%20Error%3A%20number%20%E7%B1%BB%E5%9E%8B%E4%B8%8D%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%20never%20%E7%B1%BB%E5%9E%8B%0A%0A%2F%2F%20ok%2C%20%E4%BD%9C%E4%B8%BA%E5%87%BD%E6%95%B0%E8%BF%94%E5%9B%9E%E7%B1%BB%E5%9E%8B%E7%9A%84%20never%0Alet%20bar%3A%20never%20%3D%20(()%20%3D%3E%20%7B%0A%20%20throw%20new%20Error('Throw%20my%20hands%20in%20the%20air%20like%20I%20just%20dont%20care')%3B%0A%7D)()%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E7%94%A8%E4%BE%8B%EF%BC%9A%E8%AF%A6%E7%BB%86%E7%9A%84%E6%A3%80%E6%9F%A5%0A%60%60%60ts%0Afunction%20foo(x%3A%20string%20%7C%20number)%3A%20boolean%20%7B%0A%20%20if%20(typeof%20x%20%3D%3D%3D%20'string')%20%7B%0A%20%20%20%20return%20true%3B%0A%20%20%7D%20else%20if%20(typeof%20x%20%3D%3D%3D%20'number')%20%7B%0A%20%20%20%20return%20false%3B%0A%20%20%7D%0A%0A%20%20%2F%2F%20%E5%A6%82%E6%9E%9C%E4%B8%8D%E6%98%AF%E4%B8%80%E4%B8%AA%20never%20%E7%B1%BB%E5%9E%8B%EF%BC%8C%E8%BF%99%E4%BC%9A%E6%8A%A5%E9%94%99%EF%BC%9A%0A%20%20%2F%2F%20-%20%E4%B8%8D%E6%98%AF%E6%89%80%E6%9C%89%E6%9D%A1%E4%BB%B6%E9%83%BD%E6%9C%89%E8%BF%94%E5%9B%9E%E5%80%BC%20%EF%BC%88%E4%B8%A5%E6%A0%BC%E6%A8%A1%E5%BC%8F%E4%B8%8B%EF%BC%89%0A%20%20%2F%2F%20-%20%E6%88%96%E8%80%85%E6%A3%80%E6%9F%A5%E5%88%B0%E6%97%A0%E6%B3%95%E8%AE%BF%E9%97%AE%E7%9A%84%E4%BB%A3%E7%A0%81%0A%20%20%2F%2F%20%E4%BD%86%E6%98%AF%E7%94%B1%E4%BA%8E%20TypeScript%20%E7%90%86%E8%A7%A3%20%60fail%60%20%E5%87%BD%E6%95%B0%E8%BF%94%E5%9B%9E%E4%B8%BA%20%60never%60%20%E7%B1%BB%E5%9E%8B%0A%20%20%2F%2F%20%E5%AE%83%E5%8F%AF%E4%BB%A5%E8%AE%A9%E4%BD%A0%E8%B0%83%E7%94%A8%E5%AE%83%EF%BC%8C%E5%9B%A0%E4%B8%BA%E4%BD%A0%E5%8F%AF%E8%83%BD%E4%BC%9A%E5%9C%A8%E8%BF%90%E8%A1%8C%E6%97%B6%E7%94%A8%E5%AE%83%E6%9D%A5%E5%81%9A%E5%AE%89%E5%85%A8%E6%88%96%E8%80%85%E8%AF%A6%E7%BB%86%E7%9A%84%E6%A3%80%E6%9F%A5%E3%80%82%0A%20%20return%20fail('Unexhaustive')%3B%0A%7D%0A%0Afunction%20fail(message%3A%20string)%3A%20never%20%7B%0A%20%20throw%20new%20Error(message)%3B%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E4%B8%8E%20void%20%E7%9A%84%E5%B7%AE%E5%BC%82%0A%0A%E4%B8%80%E6%97%A6%E6%9C%89%E4%BA%BA%E5%91%8A%E8%AF%89%E4%BD%A0%EF%BC%8Cnever%20%E8%A1%A8%E7%A4%BA%E4%B8%80%E4%B8%AA%E4%BB%8E%E6%9D%A5%E4%B8%8D%E4%BC%9A%E4%BC%98%E9%9B%85%E7%9A%84%E8%BF%94%E5%9B%9E%E7%9A%84%E5%87%BD%E6%95%B0%E6%97%B6%EF%BC%8C%E4%BD%A0%E5%8F%AF%E8%83%BD%E9%A9%AC%E4%B8%8A%E5%B0%B1%E4%BC%9A%E6%83%B3%E5%88%B0%E4%B8%8E%E6%AD%A4%E7%B1%BB%E4%BC%BC%E7%9A%84%20void%EF%BC%8C%E7%84%B6%E8%80%8C%E5%AE%9E%E9%99%85%E4%B8%8A%EF%BC%8Cvoid%20%E8%A1%A8%E7%A4%BA%E6%B2%A1%E6%9C%89%E4%BB%BB%E4%BD%95%E7%B1%BB%E5%9E%8B%EF%BC%8Cnever%20%E8%A1%A8%E7%A4%BA%E6%B0%B8%E8%BF%9C%E4%B8%8D%E5%AD%98%E5%9C%A8%E7%9A%84%E5%80%BC%E7%9A%84%E7%B1%BB%E5%9E%8B%E3%80%82%0Avoid%20%E6%8C%87%E5%8F%AF%E4%BB%A5%E8%A2%AB%E8%B5%8B%E5%80%BC%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%88%E5%9C%A8%20strictNullChecking%20%E4%B8%BA%20false%20%E6%97%B6%EF%BC%89%EF%BC%8C%E5%85%B6%E4%BB%96%E4%BB%BB%E4%BD%95%E7%B1%BB%E5%9E%8B%E4%B8%8D%E8%83%BD%E8%B5%8B%E5%80%BC%E7%BB%99%20never%EF%BC%8C%E9%99%A4%E4%BA%86%20never%20%E6%9C%AC%E8%BA%AB%E4%BB%A5%E5%A4%96%E3%80%82%0A%0A%23%23%20%E8%BE%A8%E6%9E%90%E8%81%94%E5%90%88%E7%B1%BB%E5%9E%8B%0A%E5%BD%93%E7%B1%BB%E4%B8%AD%E5%90%AB%E6%9C%89%E5%AD%97%E9%9D%A2%E9%87%8F%E6%88%90%E5%91%98%E6%97%B6%EF%BC%8C%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E7%94%A8%E8%AF%A5%E7%B1%BB%E7%9A%84%E5%B1%9E%E6%80%A7%E6%9D%A5%E8%BE%A8%E6%9E%90%E8%81%94%E5%90%88%E7%B1%BB%E5%9E%8B%E3%80%82%0A%E4%BD%9C%E4%B8%BA%E4%B8%80%E4%B8%AA%E4%BE%8B%E5%AD%90%EF%BC%8C%E8%80%83%E8%99%91%20Square%20%E5%92%8C%20Rectangle%20%E7%9A%84%E8%81%94%E5%90%88%E7%B1%BB%E5%9E%8B%20Shape%E3%80%82Square%20%E5%92%8C%20Rectangle%E6%9C%89%E5%85%B1%E5%90%8C%E6%88%90%E5%91%98%20kind%EF%BC%8C%E5%9B%A0%E6%AD%A4%20kind%20%E5%AD%98%E5%9C%A8%E4%BA%8E%20Shape%20%E4%B8%AD%E3%80%82%0A%60%60%60ts%0Ainterface%20Square%20%7B%0A%20%20kind%3A%20'square'%3B%0A%20%20size%3A%20number%3B%0A%7D%0A%0Ainterface%20Rectangle%20%7B%0A%20%20kind%3A%20'rectangle'%3B%0A%20%20width%3A%20number%3B%0A%20%20height%3A%20number%3B%0A%7D%0A%0Atype%20Shape%20%3D%20Square%20%7C%20Rectangle%3B%0A%60%60%60%0A%E5%A6%82%E6%9E%9C%E4%BD%A0%E4%BD%BF%E7%94%A8%E7%B1%BB%E5%9E%8B%E4%BF%9D%E6%8A%A4%E9%A3%8E%E6%A0%BC%E7%9A%84%E6%A3%80%E6%9F%A5%EF%BC%88%3D%3D%E3%80%81%3D%3D%3D%E3%80%81!%3D%E3%80%81!%3D%3D%EF%BC%89%E6%88%96%E8%80%85%E4%BD%BF%E7%94%A8%E5%85%B7%E6%9C%89%E5%88%A4%E6%96%AD%E6%80%A7%E7%9A%84%E5%B1%9E%E6%80%A7%EF%BC%88%E5%9C%A8%E8%BF%99%E9%87%8C%E6%98%AF%20kind%EF%BC%89%EF%BC%8CTypeScript%20%E5%B0%86%E4%BC%9A%E8%AE%A4%E4%B8%BA%E4%BD%A0%E4%BC%9A%E4%BD%BF%E7%94%A8%E7%9A%84%E5%AF%B9%E8%B1%A1%E7%B1%BB%E5%9E%8B%E4%B8%80%E5%AE%9A%E6%98%AF%E6%8B%A5%E6%9C%89%E7%89%B9%E6%AE%8A%E5%AD%97%E9%9D%A2%E9%87%8F%E7%9A%84%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%AE%83%E4%BC%9A%E4%B8%BA%E4%BD%A0%E8%87%AA%E5%8A%A8%E6%8A%8A%E7%B1%BB%E5%9E%8B%E8%8C%83%E5%9B%B4%E5%8F%98%E5%B0%8F%EF%BC%9A%0A%60%60%60ts%0Afunction%20area(s%3A%20Shape)%20%7B%0A%20%20if%20(s.kind%20%3D%3D%3D%20'square')%20%7B%0A%20%20%20%20%2F%2F%20%E7%8E%B0%E5%9C%A8%20TypeScript%20%E7%9F%A5%E9%81%93%20s%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%98%AF%20Square%0A%20%20%20%20%2F%2F%20%E6%89%80%E4%BB%A5%E4%BD%A0%E7%8E%B0%E5%9C%A8%E8%83%BD%E5%AE%89%E5%85%A8%E4%BD%BF%E7%94%A8%E5%AE%83%0A%20%20%20%20return%20s.size%20*%20s.size%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%2F%2F%20%E4%B8%8D%E6%98%AF%E4%B8%80%E4%B8%AA%20square%20%EF%BC%9F%E5%9B%A0%E6%AD%A4%20TypeScript%20%E5%B0%86%E4%BC%9A%E6%8E%A8%E7%AE%97%E5%87%BA%20s%20%E4%B8%80%E5%AE%9A%E6%98%AF%20Rectangle%0A%20%20%20%20return%20s.width%20*%20s.height%3B%0A%20%20%7D%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E8%AF%A6%E7%BB%86%E7%9A%84%E6%A3%80%E6%9F%A5%0A%60%60%60ts%0Ainterface%20Square%20%7B%0A%20%20kind%3A%20'square'%3B%0A%20%20size%3A%20number%3B%0A%7D%0A%0Ainterface%20Rectangle%20%7B%0A%20%20kind%3A%20'rectangle'%3B%0A%20%20width%3A%20number%3B%0A%20%20height%3A%20number%3B%0A%7D%0A%0A%2F%2F%20%E6%9C%89%E4%BA%BA%E4%BB%85%E4%BB%85%E6%98%AF%E6%B7%BB%E5%8A%A0%E4%BA%86%20%60Circle%60%20%E7%B1%BB%E5%9E%8B%0A%2F%2F%20%E6%88%91%E4%BB%AC%E5%8F%AF%E8%83%BD%E5%B8%8C%E6%9C%9B%20TypeScript%20%E8%83%BD%E5%9C%A8%E4%BB%BB%E4%BD%95%E8%A2%AB%E9%9C%80%E8%A6%81%E7%9A%84%E5%9C%B0%E6%96%B9%E6%8A%9B%E5%87%BA%E9%94%99%E8%AF%AF%0Ainterface%20Circle%20%7B%0A%20%20kind%3A%20'circle'%3B%0A%20%20radius%3A%20number%3B%0A%7D%0A%0Atype%20Shape%20%3D%20Square%20%7C%20Rectangle%20%7C%20Circle%3B%0A%60%60%60%0A%E4%B8%80%E4%B8%AA%E5%8F%AF%E8%83%BD%E4%BC%9A%E8%AE%A9%E4%BD%A0%E7%9A%84%E4%BB%A3%E7%A0%81%E5%8F%98%E5%B7%AE%E7%9A%84%E4%BE%8B%E5%AD%90%EF%BC%9A%0A%60%60%60ts%0Afunction%20area(s%3A%20Shape)%20%7B%0A%20%20if%20(s.kind%20%3D%3D%3D%20'square')%20%7B%0A%20%20%20%20return%20s.size%20*%20s.size%3B%0A%20%20%7D%20else%20if%20(s.kind%20%3D%3D%3D%20'rectangle')%20%7B%0A%20%20%20%20return%20s.width%20*%20s.height%3B%0A%20%20%7D%0A%0A%20%20%2F%2F%20%E5%A6%82%E6%9E%9C%E4%BD%A0%E8%83%BD%E8%AE%A9%20TypeScript%20%E7%BB%99%E4%BD%A0%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF%EF%BC%8C%E8%BF%99%E6%98%AF%E4%B8%8D%E6%98%AF%E5%BE%88%E6%A3%92%EF%BC%9F%0A%7D%0A%0A%60%60%60%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E7%9A%84%E5%90%91%E4%B8%8B%E6%80%9D%E6%83%B3%EF%BC%8C%E6%9D%A5%E7%A1%AE%E4%BF%9D%E5%9D%97%E4%B8%AD%E7%9A%84%E7%B1%BB%E5%9E%8B%E8%A2%AB%E6%8E%A8%E6%96%AD%E4%B8%BA%E4%B8%8E%20never%20%E7%B1%BB%E5%9E%8B%E5%85%BC%E5%AE%B9%E7%9A%84%E7%B1%BB%E5%9E%8B%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E6%B7%BB%E5%8A%A0%E4%B8%80%E4%B8%AA%E6%9B%B4%E8%AF%A6%E7%BB%86%E7%9A%84%E6%A3%80%E6%9F%A5%E6%9D%A5%E6%8D%95%E8%8E%B7%E9%94%99%E8%AF%AF%EF%BC%9A%0A%0A%60%60%60ts%0Afunction%20area(s%3A%20Shape)%20%7B%0A%20%20if%20(s.kind%20%3D%3D%3D%20'square')%20%7B%0A%20%20%20%20return%20s.size%20*%20s.size%3B%0A%20%20%7D%20else%20if%20(s.kind%20%3D%3D%3D%20'rectangle')%20%7B%0A%20%20%20%20return%20s.width%20*%20s.height%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%2F%2F%20Error%3A%20'Circle'%20%E4%B8%8D%E8%83%BD%E8%A2%AB%E8%B5%8B%E5%80%BC%E7%BB%99%20'never'%0A%20%20%20%20const%20_exhaustiveCheck%3A%20never%20%3D%20s%3B%0A%20%20%7D%0A%7D%0A%60%60%60%0A%E5%AE%83%E5%B0%86%E5%BC%BA%E5%88%B6%E4%BD%A0%E6%B7%BB%E5%8A%A0%E4%B8%80%E7%A7%8D%E6%96%B0%E7%9A%84%E6%9D%A1%E4%BB%B6%EF%BC%9A%0A%60%60%60ts%0Afunction%20area(s%3A%20Shape)%20%7B%0A%20%20if%20(s.kind%20%3D%3D%3D%20'square')%20%7B%0A%20%20%20%20return%20s.size%20*%20s.size%3B%0A%20%20%7D%20else%20if%20(s.kind%20%3D%3D%3D%20'rectangle')%20%7B%0A%20%20%20%20return%20s.width%20*%20s.height%3B%0A%20%20%7D%20else%20if%20(s.kind%20%3D%3D%3D%20'circle')%20%7B%0A%20%20%20%20return%20Math.PI%20*%20s.radius%20**%202%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20%2F%2F%20ok%0A%20%20%20%20const%20_exhaustiveCheck%3A%20never%20%3D%20s%3B%0A%20%20%7D%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20Switch%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%20switch%20%E6%9D%A5%E5%AE%9E%E7%8E%B0%E4%BB%A5%E4%B8%8A%E4%BE%8B%E5%AD%90%E3%80%82%0A%60%60%60ts%0Afunction%20area(s%3A%20Shape)%20%7B%0A%20%20switch%20(s.kind)%20%7B%0A%20%20%20%20case%20'square'%3A%0A%20%20%20%20%20%20return%20s.size%20*%20s.size%3B%0A%20%20%20%20case%20'rectangle'%3A%0A%20%20%20%20%20%20return%20s.width%20*%20s.height%3B%0A%20%20%20%20case%20'circle'%3A%0A%20%20%20%20%20%20return%20Math.PI%20*%20s.radius%20**%202%3B%0A%20%20%20%20default%3A%0A%20%20%20%20%20%20const%20_exhaustiveCheck%3A%20never%20%3D%20s%3B%0A%20%20%7D%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20strictNullChecks%0A%E5%A6%82%E6%9E%9C%E4%BD%A0%E4%BD%BF%E7%94%A8%20strictNullChecks%20%E9%80%89%E9%A1%B9%E6%9D%A5%E5%81%9A%E8%AF%A6%E7%BB%86%E7%9A%84%E6%A3%80%E6%9F%A5%EF%BC%8C%E4%BD%A0%E5%BA%94%E8%AF%A5%E8%BF%94%E5%9B%9E%20_exhaustiveCheck%20%E5%8F%98%E9%87%8F%EF%BC%88%E7%B1%BB%E5%9E%8B%E6%98%AF%20never%EF%BC%89%EF%BC%8C%E5%90%A6%E5%88%99%20TypeScript%20%E5%8F%AF%E8%83%BD%E4%BC%9A%E6%8E%A8%E6%96%AD%E8%BF%94%E5%9B%9E%E5%80%BC%E4%B8%BA%20undefined%EF%BC%9A%0A%60%60%60ts%0Afunction%20area(s%3A%20Shape)%20%7B%0A%20%20switch%20(s.kind)%20%7B%0A%20%20%20%20case%20'square'%3A%0A%20%20%20%20%20%20return%20s.size%20*%20s.size%3B%0A%20%20%20%20case%20'rectangle'%3A%0A%20%20%20%20%20%20return%20s.width%20*%20s.height%3B%0A%20%20%20%20case%20'circle'%3A%0A%20%20%20%20%20%20return%20Math.PI%20*%20s.radius%20**%202%3B%0A%20%20%20%20default%3A%0A%20%20%20%20%20%20const%20_exhaustiveCheck%3A%20never%20%3D%20s%3B%0A%20%20%20%20%20%20return%20_exhaustiveCheck%3B%0A%20%20%7D%0A%7D%0A%60%60%60%0A%0A%23%23%20%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%0A%E5%8F%AF%E4%BB%A5%E7%94%A8%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%AE%BF%E9%97%AE%20JavaScript%20%E4%B8%AD%E7%9A%84%E5%AF%B9%E8%B1%A1%EF%BC%88TypeScript%20%E4%B8%AD%E4%B9%9F%E4%B8%80%E6%A0%B7%EF%BC%89%EF%BC%8C%E7%94%A8%E6%9D%A5%E4%BF%9D%E5%AD%98%E5%AF%B9%E5%85%B6%E4%BB%96%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%BC%95%E7%94%A8%E3%80%82%0A%60%60%60ts%0Aclass%20Foo%20%7B%0A%20%20constructor(public%20message%3A%20string)%20%7B%7D%0A%20%20log()%20%7B%0A%20%20%20%20console.log(this.message)%3B%0A%20%20%7D%0A%7D%0A%0Alet%20foo%3A%20any%20%3D%20%7B%7D%3B%0Afoo%5B'Hello'%5D%20%3D%20new%20Foo('World')%3B%0Afoo%5B'Hello'%5D.log()%3B%20%2F%2F%20World%0A%60%60%60%0A%0A%E5%BD%93%E4%BD%A0%E4%BC%A0%E5%85%A5%E4%B8%80%E4%B8%AA%E5%85%B6%E4%BB%96%E5%AF%B9%E8%B1%A1%E8%87%B3%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E6%97%B6%EF%BC%8CJavaScript%20%E4%BC%9A%E5%9C%A8%E5%BE%97%E5%88%B0%E7%BB%93%E6%9E%9C%E4%B9%8B%E5%89%8D%E4%BC%9A%E5%85%88%E8%B0%83%E7%94%A8%20.toString%20%E6%96%B9%E6%B3%95%EF%BC%9A%0A%60%60%60TS%0A%2F%2F%E5%8F%AA%E8%A6%81%E7%B4%A2%E5%BC%95%E4%BD%8D%E7%BD%AE%E4%BD%BF%E7%94%A8%E4%BA%86%20obj%EF%BC%8CtoString%20%E6%96%B9%E6%B3%95%E9%83%BD%E5%B0%86%E4%BC%9A%E8%A2%AB%E8%B0%83%E7%94%A8%E3%80%82%0Alet%20obj%20%3D%20%7B%0A%20%20toString()%20%7B%0A%20%20%20%20console.log('toString%20called')%3B%0A%20%20%20%20return%20'Hello'%3B%0A%20%20%7D%0A%7D%3B%0A%0Alet%20foo%3A%20any%20%3D%20%7B%7D%3B%0Afoo%5Bobj%5D%20%3D%20'World'%3B%20%2F%2F%20toString%20called%0Aconsole.log(foo%5Bobj%5D)%3B%20%2F%2F%20toString%20called%2C%20World%0Aconsole.log(foo%5B'Hello'%5D)%3B%20%2F%2F%20World%0A%60%60%60%0A%0A%3Cu%3E%E6%95%B0%E7%BB%84%E6%9C%89%E7%82%B9%E7%A8%8D%E5%BE%AE%E4%B8%8D%E5%90%8C%EF%BC%8C%E5%AF%B9%E4%BA%8E%E4%B8%80%E4%B8%AA%20number%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%EF%BC%8CJavaScript%20%E5%BC%95%E6%93%8E%E5%B0%86%E4%BC%9A%E5%B0%9D%E8%AF%95%E5%8E%BB%E4%BC%98%E5%8C%96%EF%BC%88%E8%BF%99%E5%8F%96%E5%86%B3%E4%BA%8E%E5%AE%83%E6%98%AF%E5%90%A6%E6%98%AF%E4%B8%80%E4%B8%AA%E7%9C%9F%E7%9A%84%E6%95%B0%E7%BB%84%E3%80%81%E5%AD%98%E5%82%A8%E7%9A%84%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84%E6%98%AF%E5%90%A6%E5%8C%B9%E9%85%8D%E7%AD%89%EF%BC%89%E3%80%82%E5%9B%A0%E6%AD%A4%EF%BC%8Cnumber%20%E5%BA%94%E8%AF%A5%E8%A2%AB%E8%80%83%E8%99%91%E4%BD%9C%E4%B8%BA%E4%B8%80%E4%B8%AA%E6%9C%89%E6%95%88%E7%9A%84%E5%AF%B9%E8%B1%A1%E8%AE%BF%E9%97%AE%E5%99%A8%EF%BC%88%E8%BF%99%E4%B8%8E%20string%20%E4%B8%8D%E5%90%8C%EF%BC%89%EF%BC%8C%E5%A6%82%E4%B8%8B%E4%BE%8B%E5%AD%90%3C%2Fu%3E%0A%60%60%60TS%0Alet%20foo%20%3D%20%5B'World'%5D%3B%0Aconsole.log(foo%5B0%5D)%3B%20%2F%2F%20World%0A%60%60%60%0A%0A%23%23%23%23%20TypeScript%20%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%0AJavaScript%20%E5%9C%A8%E4%B8%80%E4%B8%AA%E5%AF%B9%E8%B1%A1%E7%B1%BB%E5%9E%8B%E7%9A%84%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E4%B8%8A%E4%BC%9A%E9%9A%90%E5%BC%8F%E8%B0%83%E7%94%A8%20toString%20%E6%96%B9%E6%B3%95%EF%BC%8C%E8%80%8C%E5%9C%A8%20TypeScript%20%E4%B8%AD%EF%BC%8C%E4%B8%BA%E9%98%B2%E6%AD%A2%E5%88%9D%E5%AD%A6%E8%80%85%E7%A0%B8%E4%BC%A4%E8%87%AA%E5%B7%B1%E7%9A%84%E8%84%9A%EF%BC%88%E6%88%91%E6%80%BB%E6%98%AF%E7%9C%8B%E5%88%B0%20stackoverflow%20%E4%B8%8A%E6%9C%89%E5%BE%88%E5%A4%9A%20JavaScript%20%E4%BD%BF%E7%94%A8%E8%80%85%E9%83%BD%E4%BC%9A%E8%BF%99%E6%A0%B7%E3%80%82%EF%BC%89%EF%BC%8C%E5%AE%83%E5%B0%86%E4%BC%9A%E6%8A%9B%E5%87%BA%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF%E3%80%82%0A%60%60%60TS%0Aconst%20obj%20%3D%20%7B%0A%20%20toString()%20%7B%0A%20%20%20%20return%20'Hello'%3B%0A%20%20%7D%0A%7D%3B%0A%0Aconst%20foo%3A%20any%20%3D%20%7B%7D%3B%0A%0A%2F%2F%20ERROR%3A%20%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E5%BF%85%E9%A1%BB%E4%B8%BA%20string%2C%20number....%0Afoo%5Bobj%5D%20%3D%20'World'%3B%0A%0A%2F%2F%20FIX%3A%20TypeScript%20%E5%BC%BA%E5%88%B6%E4%BD%A0%E5%BF%85%E9%A1%BB%E6%98%8E%E7%A1%AE%E8%BF%99%E4%B9%88%E5%81%9A%EF%BC%9A%0Afoo%5Bobj.toString()%5D%20%3D%20'World'%3B%0A%60%60%60%0A%E5%BC%BA%E5%88%B6%E7%94%A8%E6%88%B7%E5%BF%85%E9%A1%BB%E6%98%8E%E7%A1%AE%E7%9A%84%E5%86%99%E5%87%BA%20toString()%20%E7%9A%84%E5%8E%9F%E5%9B%A0%E6%98%AF%EF%BC%9A%E5%9C%A8%E5%AF%B9%E8%B1%A1%E4%B8%8A%E9%BB%98%E8%AE%A4%E6%89%A7%E8%A1%8C%E7%9A%84%20toString%20%E6%96%B9%E6%B3%95%E6%98%AF%E6%9C%89%E5%AE%B3%E7%9A%84%E3%80%82%E4%BE%8B%E5%A6%82%20v8%20%E5%BC%95%E6%93%8E%E4%B8%8A%E6%80%BB%E6%98%AF%E4%BC%9A%E8%BF%94%E5%9B%9E%20%5Bobject%20Object%5D%0A%60%60%60TS%0Aconst%20obj%20%3D%20%7B%20message%3A%20'Hello'%20%7D%3B%0Alet%20foo%3A%20any%20%3D%20%7B%7D%3B%0A%0A%2F%2F%20ERROR%3A%20%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E5%BF%85%E9%A1%BB%E4%B8%BA%20string%2C%20number....%0Afoo%5Bobj%5D%20%3D%20'World'%3B%0A%0A%2F%2F%20%E8%BF%99%E9%87%8C%E5%AE%9E%E9%99%85%E4%B8%8A%E5%B0%B1%E6%98%AF%E4%BD%A0%E5%AD%98%E5%82%A8%E7%9A%84%E5%9C%B0%E6%96%B9%0Aconsole.log(foo%5B'%5Bobject%20Object%5D'%5D)%3B%20%2F%2F%20World%0A%60%60%60%0A*TypeScript%20%E7%9A%84%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E5%BF%85%E9%A1%BB%E6%98%AF%20string%20%E6%88%96%E8%80%85%20number%E3%80%82%0Asymbols%20%E4%B9%9F%E6%98%AF%E6%9C%89%E6%95%88%E7%9A%84%EF%BC%8CTypeScript%20%E6%94%AF%E6%8C%81%E5%AE%83%E3%80%82*%0A%0A%23%23%23%23%20%E5%A3%B0%E6%98%8E%E4%B8%80%E4%B8%AA%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%0A%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E6%98%8E%E7%A1%AE%E7%9A%84%E6%8C%87%E5%AE%9A%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%9A%E5%81%87%E8%AE%BE%E4%BD%A0%E6%83%B3%E7%A1%AE%E8%AE%A4%E5%AD%98%E5%82%A8%E5%9C%A8%E5%AF%B9%E8%B1%A1%E4%B8%AD%E4%BB%BB%E4%BD%95%E5%86%85%E5%AE%B9%E9%83%BD%E7%AC%A6%E5%90%88%20%7B%20message%3A%20string%20%7D%20%E7%9A%84%E7%BB%93%E6%9E%84%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%20%5Bindex%3A%20string%5D%3A%20%7B%20message%3A%20string%20%7D%20%E6%9D%A5%E5%AE%9E%E7%8E%B0%E3%80%82%0A%60%60%60TS%0Aconst%20foo%3A%20%7B%0A%20%20%5Bindex%3A%20string%5D%3A%20%7B%20message%3A%20string%20%7D%3B%0A%7D%20%3D%20%7B%7D%3B%0A%0A%2F%2F%20%E5%82%A8%E5%AD%98%E7%9A%84%E4%B8%9C%E8%A5%BF%E5%BF%85%E9%A1%BB%E7%AC%A6%E5%90%88%E7%BB%93%E6%9E%84%0A%2F%2F%20ok%0Afoo%5B'a'%5D%20%3D%20%7B%20message%3A%20'some%20message'%20%7D%3B%0A%0A%2F%2F%20Error%2C%20%E5%BF%85%E9%A1%BB%E5%8C%85%E5%90%AB%20%60message%60%0Afoo%5B'a'%5D%20%3D%20%7B%20messages%3A%20'some%20message'%20%7D%3B%0A%0A%2F%2F%20%E8%AF%BB%E5%8F%96%E6%97%B6%EF%BC%8C%E4%B9%9F%E4%BC%9A%E6%9C%89%E7%B1%BB%E5%9E%8B%E6%A3%80%E6%9F%A5%0A%2F%2F%20ok%0Afoo%5B'a'%5D.message%3B%0A%0A%2F%2F%20Error%3A%20messages%20%E4%B8%8D%E5%AD%98%E5%9C%A8%0Afoo%5B'a'%5D.messages%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E6%89%80%E6%9C%89%E6%88%90%E5%91%98%E9%83%BD%E5%BF%85%E9%A1%BB%E7%AC%A6%E5%90%88%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%0A%E5%BD%93%E4%BD%A0%E5%A3%B0%E6%98%8E%E4%B8%80%E4%B8%AA%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E6%97%B6%EF%BC%8C%E6%89%80%E6%9C%89%E6%98%8E%E7%A1%AE%E7%9A%84%E6%88%90%E5%91%98%E9%83%BD%E5%BF%85%E9%A1%BB%E7%AC%A6%E5%90%88%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%EF%BC%9A%0A%60%60%60TS%0A%2F%2F%20ok%0Ainterface%20Foo%20%7B%0A%20%20%5Bkey%3A%20string%5D%3A%20number%3B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%7D%0A%0A%2F%2F%20Error%0Ainterface%20Bar%20%7B%0A%20%20%5Bkey%3A%20string%5D%3A%20number%3B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20string%3B%20%2F%2F%20Error%3A%20y%20%E5%B1%9E%E6%80%A7%E5%BF%85%E9%A1%BB%E4%B8%BA%20number%20%E7%B1%BB%E5%9E%8B%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E4%BD%BF%E7%94%A8%E4%B8%80%E7%BB%84%E6%9C%89%E9%99%90%E7%9A%84%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%AD%97%E9%9D%A2%E9%87%8F%0A%E4%B8%80%E4%B8%AA%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E6%98%A0%E5%B0%84%E7%B1%BB%E5%9E%8B%E6%9D%A5%E4%BD%BF%E7%B4%A2%E5%BC%95%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%BA%E8%81%94%E5%90%88%E7%B1%BB%E5%9E%8B%E4%B8%AD%E7%9A%84%E4%B8%80%E5%91%98%EF%BC%8C%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%EF%BC%9A%0A%60%60%60TS%0Atype%20Index%20%3D%20'a'%20%7C%20'b'%20%7C%20'c'%3B%0Atype%20FromIndex%20%3D%20%7B%20%5Bk%20in%20Index%5D%3F%3A%20number%20%7D%3B%0A%0Aconst%20good%3A%20FromIndex%20%3D%20%7B%20b%3A%201%2C%20c%3A%202%20%7D%3B%0A%0A%2F%2F%20Error%3A%0A%2F%2F%20%60%7B%20b%3A%201%2C%20c%3A%202%2C%20d%3A%203%20%7D%60%20%E4%B8%8D%E8%83%BD%E5%88%86%E9%85%8D%E7%BB%99%20'FromIndex'%0A%2F%2F%20%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E5%8F%AA%E8%83%BD%E6%8C%87%E5%AE%9A%E5%B7%B2%E7%9F%A5%E7%B1%BB%E5%9E%8B%EF%BC%8C'd'%20%E4%B8%8D%E5%AD%98%E5%9C%A8%20'FromIndex'%20%E7%B1%BB%E5%9E%8B%E4%B8%8A%0Aconst%20bad%3A%20FromIndex%20%3D%20%7B%20b%3A%201%2C%20c%3A%202%2C%20d%3A%203%20%7D%3B%0A%60%60%60%0A%0A%E5%8F%98%E9%87%8F%E7%9A%84%E8%A7%84%E5%88%99%E4%B8%80%E8%88%AC%E5%8F%AF%E4%BB%A5%E5%BB%B6%E8%BF%9F%E8%A2%AB%E6%8E%A8%E6%96%AD%EF%BC%9A%0A%60%60%60TS%0Atype%20FromSomeIndex%3CK%20extends%20string%3E%20%3D%20%7B%20%5Bkey%20in%20K%5D%3A%20number%20%7D%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E5%90%8C%E6%97%B6%E6%8B%A5%E6%9C%89%20string%20%E5%92%8C%20number%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%0Astring%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E6%AF%94%20number%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E6%9B%B4%E4%B8%A5%E6%A0%BC%E3%80%82%E8%BF%99%E6%98%AF%E6%95%85%E6%84%8F%E8%AE%BE%E8%AE%A1%EF%BC%8C%E5%AE%83%E5%85%81%E8%AE%B8%E4%BD%A0%E6%9C%89%E5%A6%82%E4%B8%8B%E7%B1%BB%E5%9E%8B%EF%BC%9A%0A%60%60%60TS%0Ainterface%20ArrStr%20%7B%0A%20%20%5Bkey%3A%20string%5D%3A%20string%20%7C%20number%3B%20%2F%2F%20%E5%BF%85%E9%A1%BB%E5%8C%85%E6%8B%AC%E6%89%80%E7%94%A8%E6%88%90%E5%91%98%E7%B1%BB%E5%9E%8B%0A%20%20%5Bindex%3A%20number%5D%3A%20string%3B%20%2F%2F%20%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%B4%A2%E5%BC%95%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%AD%90%E7%BA%A7%0A%0A%20%20%2F%2F%20example%0A%20%20length%3A%20number%3B%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%EF%BC%9A%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E7%9A%84%E5%B5%8C%E5%A5%97%0A%60%60%60TS%0Ainterface%20NestedCSS%20%7B%0A%20%20color%3F%3A%20string%3B%20%2F%2F%20strictNullChecks%3Dfalse%20%E6%97%B6%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E5%8F%AF%E4%B8%BA%20undefined%0A%20%20%5Bselector%3A%20string%5D%3A%20string%20%7C%20NestedCSS%3B%0A%7D%0A%0Aconst%20example%3A%20NestedCSS%20%3D%20%7B%0A%20%20color%3A%20'red'%2C%0A%20%20'.subclass'%3A%20%7B%0A%20%20%20%20color%3A%20'blue'%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%E5%B0%BD%E9%87%8F%E4%B8%8D%E8%A6%81%E4%BD%BF%E7%94%A8%E8%BF%99%E7%A7%8D%E6%8A%8A%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E4%B8%8E%E6%9C%89%E6%95%88%E5%8F%98%E9%87%8F%E6%B7%B7%E5%90%88%E4%BD%BF%E7%94%A8%E3%80%82%E5%A6%82%E6%9E%9C%E5%B1%9E%E6%80%A7%E5%90%8D%E7%A7%B0%E4%B8%AD%E6%9C%89%E6%8B%BC%E5%86%99%E9%94%99%E8%AF%AF%EF%BC%8C%E8%BF%99%E4%B8%AA%E9%94%99%E8%AF%AF%E4%B8%8D%E4%BC%9A%E8%A2%AB%E6%8D%95%E8%8E%B7%E5%88%B0%EF%BC%9A%0Aconst%20failsSilently%3A%20NestedCSS%20%3D%20%7B%0A%20%20colour%3A%20'red'%20%2F%2F%20'colour'%20%E4%B8%8D%E4%BC%9A%E8%A2%AB%E6%8D%95%E6%8D%89%E5%88%B0%E9%94%99%E8%AF%AF%0A%7D%3B%0A%0A%2F%2F%E5%8F%96%E8%80%8C%E4%BB%A3%E4%B9%8B%EF%BC%8C%E6%88%91%E4%BB%AC%E6%8A%8A%E7%B4%A2%E5%BC%95%E7%AD%BE%E5%90%8D%E5%88%86%E7%A6%BB%E5%88%B0%E8%87%AA%E5%B7%B1%E7%9A%84%E5%B1%9E%E6%80%A7%E9%87%8C%EF%BC%8C%E5%A6%82%E5%91%BD%E5%90%8D%E4%B8%BA%20nest%EF%BC%88%E6%88%96%E8%80%85%20children%E3%80%81subnodes%20%E7%AD%89%EF%BC%89%EF%BC%9A%0Ainterface%20NestedCSS%20%7B%0A%20%20color%3F%3A%20string%3B%0A%20%20nest%3F%3A%20%7B%0A%20%20%20%20%5Bselector%3A%20string%5D%3A%20NestedCSS%3B%0A%20%20%7D%3B%0A%7D%0A%0Aconst%20example%3A%20NestedCSS%20%3D%20%7B%0A%20%20color%3A%20'red'%2C%0A%20%20nest%3A%20%7B%0A%20%20%20%20'.subclass'%3A%20%7B%0A%20%20%20%20%20%20color%3A%20'blue'%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A%0Aconst%20failsSliently%3A%20NestedCSS%20%7B%0A%20%20colour%3A%20'red'%20%20%2F%2F%20TS%20Error%3A%20%E6%9C%AA%E7%9F%A5%E5%B1%9E%E6%80%A7%20'colour'%0A%7D%0A%60%60%60%0A%0A%23%23%20%E6%B5%81%E5%8A%A8%E7%9A%84%E7%B1%BB%E5%9E%8B%0A%0A%23%23%23%23%20%E5%A4%8D%E5%88%B6%E7%B1%BB%E5%9E%8B%E5%92%8C%E5%80%BC%0A%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%83%B3%E7%A7%BB%E5%8A%A8%E4%B8%80%E4%B8%AA%E7%B1%BB%EF%BC%8C%E4%BD%A0%E5%8F%AF%E8%83%BD%E4%BC%9A%E6%83%B3%E8%A6%81%E5%81%9A%E4%BB%A5%E4%B8%8B%E4%BA%8B%E6%83%85%EF%BC%9A%0A%60%60%60TS%0Aclass%20Foo%20%7B%7D%0A%0Aconst%20Bar%20%3D%20Foo%3B%0A%0Alet%20bar%3A%20Bar%3B%20%2F%2F%20Error%3A%20%E4%B8%8D%E8%83%BD%E6%89%BE%E5%88%B0%E5%90%8D%E7%A7%B0%20'Bar'%0A%60%60%60%0A%E5%9B%A0%E4%B8%BA%20const%20%E4%BB%85%E4%BB%85%E6%98%AF%E5%A4%8D%E5%88%B6%E4%BA%86%20Foo%20%E5%88%B0%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E5%A3%B0%E6%98%8E%E7%A9%BA%E9%97%B4%EF%BC%8C%E5%9B%A0%E6%AD%A4%E4%BD%A0%E6%97%A0%E6%B3%95%E6%8A%8A%20Bar%20%E5%BD%93%E4%BD%9C%E4%B8%80%E4%B8%AA%E7%B1%BB%E5%9E%8B%E5%A3%B0%E6%98%8E%E4%BD%BF%E7%94%A8%E3%80%82%E6%AD%A3%E7%A1%AE%E7%9A%84%E6%96%B9%E5%BC%8F%E6%98%AF%E4%BD%BF%E7%94%A8%20import%20%E5%85%B3%E9%94%AE%E5%AD%97%EF%BC%8C%E8%AF%B7%E6%B3%A8%E6%84%8F%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E5%9C%A8%E4%BD%BF%E7%94%A8%20namespace%20%E6%88%96%E8%80%85%20modules%EF%BC%8C%E4%BD%BF%E7%94%A8%20import%20%E6%98%AF%E4%BD%A0%E5%94%AF%E4%B8%80%E8%83%BD%E7%94%A8%E7%9A%84%E6%96%B9%E5%BC%8F%EF%BC%9A%0A%60%60%60TS%0Anamespace%20importing%20%7B%0A%20%20export%20class%20Foo%20%7B%7D%0A%7D%0A%0Aimport%20Bar%20%3D%20importing.Foo%3B%0Alet%20bar%3A%20Bar%3B%20%2F%2F%20ok%0A%60%60%60%0A*%E8%BF%99%E4%B8%AA%20import%20%E6%8A%80%E5%B7%A7%EF%BC%8C%E4%BB%85%E9%80%82%E5%90%88%E4%BA%8E%E7%B1%BB%E5%9E%8B%E5%92%8C%E5%8F%98%E9%87%8F%E3%80%82*%0A%0A%23%23%23%23%20%E6%8D%95%E8%8E%B7%E5%8F%98%E9%87%8F%E7%9A%84%E7%B1%BB%E5%9E%8B%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%20typeof%20%E6%93%8D%E4%BD%9C%E7%AC%A6%E5%9C%A8%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%8F%98%E9%87%8F%E3%80%82%E8%BF%99%E5%85%81%E8%AE%B8%E4%BD%A0%E5%91%8A%E8%AF%89%E7%BC%96%E8%AF%91%E5%99%A8%EF%BC%8C%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E7%9A%84%E7%B1%BB%E5%9E%8B%E4%B8%8E%E5%85%B6%E4%BB%96%E7%B1%BB%E5%9E%8B%E7%9B%B8%E5%90%8C%EF%BC%8C%E5%A6%82%E4%B8%8B%E6%89%80%E7%A4%BA%EF%BC%9A%0A%60%60%60TS%0Alet%20foo%20%3D%20123%3B%0Alet%20bar%3A%20typeof%20foo%3B%20%2F%2F%20'bar'%20%E7%B1%BB%E5%9E%8B%E4%B8%8E%20'foo'%20%E7%B1%BB%E5%9E%8B%E7%9B%B8%E5%90%8C%EF%BC%88%E5%9C%A8%E8%BF%99%E9%87%8C%E6%98%AF%EF%BC%9A%20'number'%EF%BC%89%0A%0Abar%20%3D%20456%3B%20%2F%2F%20ok%0Abar%20%3D%20'789'%3B%20%2F%2F%20Error%3A%20'string'%20%E4%B8%8D%E8%83%BD%E5%88%86%E9%85%8D%E7%BB%99%20'number'%20%E7%B1%BB%E5%9E%8B%0A%60%60%60%0A%0A%23%23%23%23%20%E6%8D%95%E8%8E%B7%E7%B1%BB%E6%88%90%E5%91%98%E7%9A%84%E7%B1%BB%E5%9E%8B%0A%E4%B8%8E%E6%8D%95%E8%8E%B7%E5%8F%98%E9%87%8F%E7%9A%84%E7%B1%BB%E5%9E%8B%E7%9B%B8%E4%BC%BC%EF%BC%8C%E4%BD%A0%E4%BB%85%E4%BB%85%E6%98%AF%E9%9C%80%E8%A6%81%E5%A3%B0%E6%98%8E%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E7%94%A8%E6%9D%A5%E6%8D%95%E8%8E%B7%E5%88%B0%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%9A%0A%60%60%60TS%0Aclass%20Foo%20%7B%0A%20%20foo%3A%20number%3B%20%2F%2F%20%E6%88%91%E4%BB%AC%E6%83%B3%E8%A6%81%E6%8D%95%E8%8E%B7%E7%9A%84%E7%B1%BB%E5%9E%8B%0A%7D%0A%0Adeclare%20let%20_foo%3A%20Foo%3B%0A%0A%2F%2F%20%E4%B8%8E%E4%B9%8B%E5%89%8D%E5%81%9A%E6%B3%95%E7%9B%B8%E5%90%8C%0Alet%20bar%3A%20typeof%20_foo.foo%3B%0A%60%60%60%0A%0A%23%23%23%23%20%E6%8D%95%E8%8E%B7%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%B1%BB%E5%9E%8B%0A%E8%AE%B8%E5%A4%9A%20JavaScript%20%E5%BA%93%E5%92%8C%E6%A1%86%E6%9E%B6%E9%83%BD%E4%BD%BF%E7%94%A8%E5%8E%9F%E5%A7%8B%E7%9A%84%20JavaScript%20%E5%AD%97%E7%AC%A6%E4%B8%B2%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%20const%20%E5%AE%9A%E4%B9%89%E4%B8%80%E4%B8%AA%E5%8F%98%E9%87%8F%E6%8D%95%E8%8E%B7%E5%AE%83%E7%9A%84%E7%B1%BB%E5%9E%8B%EF%BC%9A%0A%60%60%60TS%0A%2F%2F%20%E6%8D%95%E8%8E%B7%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E7%B1%BB%E5%9E%8B%E4%B8%8E%E5%80%BC%0Aconst%20foo%20%3D%20'Hello%20World'%3B%20%2F%2F%E5%AD%97%E9%9D%A2%E9%87%8F%E7%B1%BB%E5%9E%8B%0A%0A%2F%2F%20%E4%BD%BF%E7%94%A8%E4%B8%80%E4%B8%AA%E6%8D%95%E8%8E%B7%E7%9A%84%E7%B1%BB%E5%9E%8B%0Alet%20bar%3A%20typeof%20foo%3B%0A%0A%2F%2F%20bar%20%E4%BB%85%E8%83%BD%E8%A2%AB%E8%B5%8B%E5%80%BC%20'Hello%20World'%20%20%0Abar%20%3D%20'Hello%20World'%3B%20%2F%2F%20ok%0Abar%20%3D%20'anything%20else'%3B%20%2F%2F%20Error%0A%60%60%60%0A%0A%23%23%23%23%20%E6%8D%95%E8%8E%B7%E9%94%AE%E7%9A%84%E5%90%8D%E7%A7%B0%0Akeyof%20%E6%93%8D%E4%BD%9C%E7%AC%A6%E8%83%BD%E8%AE%A9%E4%BD%A0%E6%8D%95%E8%8E%B7%E4%B8%80%E4%B8%AA%E7%B1%BB%E5%9E%8B%E7%9A%84%E9%94%AE%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%8C%E4%BD%A0%E5%8F%AF%E4%BB%A5%E4%BD%BF%E7%94%A8%E5%AE%83%E6%9D%A5%E6%8D%95%E8%8E%B7%E5%8F%98%E9%87%8F%E7%9A%84%E9%94%AE%E5%90%8D%E7%A7%B0%EF%BC%8C%E5%9C%A8%E9%80%9A%E8%BF%87%E4%BD%BF%E7%94%A8%20typeof%20%E6%9D%A5%E8%8E%B7%E5%8F%96%E7%B1%BB%E5%9E%8B%E4%B9%8B%E5%90%8E%EF%BC%9A%0A%60%60%60TS%0Aconst%20colors%20%3D%20%7B%0A%20%20red%3A%20'red'%2C%0A%20%20blue%3A%20'blue'%0A%7D%3B%0A%0Atype%20Colors%20%3D%20keyof%20typeof%20colors%3B%0A%0Alet%20color%3A%20Colors%3B%20%2F%2F%20color%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E6%98%AF%20'red'%20%7C%20'blue'%0Acolor%20%3D%20'red'%3B%20%2F%2F%20ok%0Acolor%20%3D%20'blue'%3B%20%2F%2F%20ok%0Acolor%20%3D%20'anythingElse'%3B%20%2F%2F%20Error%0A%60%60%60%0A%0A%23%23%20%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%0AJavaScript%20%E6%9C%89%E4%B8%80%E4%B8%AA%20Error%20%E7%B1%BB%EF%BC%8C%E7%94%A8%E4%BA%8E%E5%A4%84%E7%90%86%E5%BC%82%E5%B8%B8%E3%80%82%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%20throw%20%E5%85%B3%E9%94%AE%E5%AD%97%E6%9D%A5%E6%8A%9B%E5%87%BA%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF%E3%80%82%E7%84%B6%E5%90%8E%E9%80%9A%E8%BF%87%20try%2Fcatch%20%E5%9D%97%E6%9D%A5%E6%8D%95%E8%8E%B7%E6%AD%A4%E9%94%99%E8%AF%AF%EF%BC%9A%0A%60%60%60TS%0Atry%20%7B%0A%20%20throw%20new%20Error('Something%20bad%20happened')%3B%0A%7D%20catch%20(e)%20%7B%0A%20%20console.log(e)%3B%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E9%94%99%E8%AF%AF%E5%AD%90%E7%B1%BB%E5%9E%8B%0A%E9%99%A4%E5%86%85%E7%BD%AE%E7%9A%84%20Error%20%E7%B1%BB%E5%A4%96%EF%BC%8C%E8%BF%98%E6%9C%89%E4%B8%80%E4%BA%9B%E9%A2%9D%E5%A4%96%E7%9A%84%E5%86%85%E7%BD%AE%E9%94%99%E8%AF%AF%EF%BC%8C%E5%AE%83%E4%BB%AC%E7%BB%A7%E6%89%BF%E8%87%AA%20Error%20%E7%B1%BB%EF%BC%9A%0A%23%23%23%23%23%20RangeError%0A%E5%BD%93%E6%95%B0%E5%AD%97%E7%B1%BB%E5%9E%8B%E5%8F%98%E9%87%8F%E6%88%96%E8%80%85%E5%8F%82%E6%95%B0%E8%B6%85%E5%87%BA%E5%85%B6%E6%9C%89%E6%95%88%E8%8C%83%E5%9B%B4%E6%97%B6%EF%BC%8C%E5%87%BA%E7%8E%B0%20RangeError%20%E7%9A%84%E9%94%99%E8%AF%AF%E6%8F%90%E7%A4%BA%EF%BC%9A%0A%60%60%60TS%0A%2F%2F%20%E4%BD%BF%E7%94%A8%E8%BF%87%E5%A4%9A%E5%8F%82%E6%95%B0%E8%B0%83%E7%94%A8%20console%0Aconsole.log.apply(console%2C%20new%20Array(1000000000))%3B%20%2F%2F%20RangeError%3A%20%E6%95%B0%E7%BB%84%E9%95%BF%E5%BA%A6%E6%97%A0%E6%95%88%0A%60%60%60%0A%0A%23%23%23%23%23%20ReferenceError%0A%E5%BD%93%E5%BC%95%E7%94%A8%E6%97%A0%E6%95%88%E6%97%B6%EF%BC%8C%E4%BC%9A%E5%87%BA%E7%8E%B0%20ReferenceError%20%E7%9A%84%E9%94%99%E8%AF%AF%E6%8F%90%E7%A4%BA%EF%BC%9A%0A%60%60%60TS%0A'use%20strict'%3B%0Aconsole.log(notValidVar)%3B%20%2F%2F%20ReferenceError%3A%20notValidVar%20%E6%9C%AA%E5%AE%9A%E4%B9%89%0A%60%60%60%0A%0A%23%23%23%23%23%20SyntaxError%0A%E5%BD%93%E8%A7%A3%E6%9E%90%E6%97%A0%E6%95%88%20JavaScript%20%E4%BB%A3%E7%A0%81%E6%97%B6%EF%BC%8C%E4%BC%9A%E5%87%BA%E7%8E%B0%20SyntaxError%20%E7%9A%84%E9%94%99%E8%AF%AF%E6%8F%90%E7%A4%BA%EF%BC%9A%0A%60%60%60TS%0A1%20***%203%20%20%20%2F%2F%20SyntaxError%3A%20%E6%97%A0%E6%95%88%E7%9A%84%E6%A0%87%E8%AE%B0%20*%0A%60%60%60%0A%0A%23%23%23%23%23%20TypeError%0A%E5%8F%98%E9%87%8F%E6%88%96%E8%80%85%E5%8F%82%E6%95%B0%E4%B8%8D%E6%98%AF%E6%9C%89%E6%95%88%E7%B1%BB%E5%9E%8B%E6%97%B6%EF%BC%8C%E4%BC%9A%E5%87%BA%E7%8E%B0%20TypeError%20%E7%9A%84%E9%94%99%E8%AF%AF%E6%8F%90%E7%A4%BA%EF%BC%9A%0A%60%60%60TS%0A'1.2'.toPrecision(1)%3B%20%2F%2F%20TypeError%3A%20'1.2'.toPrecision%20%E4%B8%8D%E6%98%AF%E5%87%BD%E6%95%B0%E3%80%82%0A%60%60%60%0A%0A%23%23%23%23%23%20URIError%0A%E5%BD%93%E4%BC%A0%E5%85%A5%E6%97%A0%E6%95%88%E5%8F%82%E6%95%B0%E8%87%B3%20encodeURI()%20%E5%92%8C%20decodeURI()%20%E6%97%B6%EF%BC%8C%E4%BC%9A%E5%87%BA%E7%8E%B0%20URIError%20%E7%9A%84%E9%94%99%E8%AF%AF%E6%8F%90%E7%A4%BA%EF%BC%9A%0A%60%60%60TS%0AdecodeURI('%25')%3B%20%2F%2F%20URIError%3A%20URL%20%E5%BC%82%E5%B8%B8%0A%60%60%60%0A%0A%23%23%23%23%20%E4%BD%BF%E7%94%A8%20Error%0A%0A%60%60%60%0Atry%20%7B%0A%20%20throw%20'Something%20bad%20happened'%3B%0A%7D%20catch%20(e)%20%7B%0A%20%20console.log(e)%3B%0A%7D%0A%60%60%60%0A**%E4%B8%8D%E8%A6%81%E8%BF%99%E4%B9%88%E5%81%9A**%EF%BC%8C%E4%BD%BF%E7%94%A8%20Error%20%E5%AF%B9%E8%B1%A1%E7%9A%84%E5%9F%BA%E6%9C%AC%E5%A5%BD%E5%A4%84%E6%98%AF%EF%BC%8C%E5%AE%83%E8%83%BD%E8%87%AA%E5%8A%A8%E8%B7%9F%E8%B8%AA%E5%A0%86%E6%A0%88%E7%9A%84%E5%B1%9E%E6%80%A7%E6%9E%84%E5%BB%BA%E4%BB%A5%E5%8F%8A%E7%94%9F%E6%88%90%E4%BD%8D%E7%BD%AE%E3%80%82%0A%E5%8E%9F%E5%A7%8B%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%BC%9A%E5%AF%BC%E8%87%B4%E6%9E%81%E5%B7%AE%E7%9A%84%E8%B0%83%E8%AF%95%E4%BD%93%E9%AA%8C%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%9C%A8%E5%88%86%E6%9E%90%E6%97%A5%E5%BF%97%E6%97%B6%EF%BC%8C%E5%B0%86%E4%BC%9A%E5%8F%98%E5%BE%97%E9%94%99%E7%BB%BC%E5%A4%8D%E6%9D%82%E3%80%82%0A%0A%23%23%23%23%20%E4%BD%A0%E5%B9%B6%E4%B8%8D%E9%9C%80%E8%A6%81%20throw%20%E6%8A%9B%E5%87%BA%E4%B8%80%E4%B8%AA%E9%94%99%E8%AF%AF%0A%E4%BC%A0%E9%80%92%E4%B8%80%E4%B8%AA%20Error%20%E5%AF%B9%E8%B1%A1%E6%98%AF%E6%B2%A1%E9%97%AE%E9%A2%98%E7%9A%84%EF%BC%8C%E8%BF%99%E7%A7%8D%E6%96%B9%E5%BC%8F%E5%9C%A8%20Node.js%20%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E4%B8%AD%E9%9D%9E%E5%B8%B8%E5%B8%B8%E8%A7%81%EF%BC%8C%E5%AE%83%E7%94%A8%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%8F%82%E6%95%B0%E4%BD%9C%E4%B8%BA%E9%94%99%E8%AF%AF%E5%AF%B9%E8%B1%A1%E8%BF%9B%E8%A1%8C%E5%9B%9E%E8%B0%83%E5%A4%84%E7%90%86%E3%80%82%0A%60%60%60TS%0Afunction%20myFunction%20(callback%3A%20(e%3A%20Error))%20%7B%0A%20%20doSomethingAsync(function%20()%20%7B%0A%20%20%20%20if%20(somethingWrong)%20%7B%0A%20%20%20%20%20%20callback(new%20Error('This%20is%20my%20error'))%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20callback()%3B%0A%20%20%20%20%7D%0A%20%20%7D)%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%20%E4%BC%98%E7%A7%80%E7%9A%84%E7%94%A8%E4%BE%8B%0A%23%23%23%23%23%20%E4%B8%8D%E6%B8%85%E6%A5%9A%E4%BB%8E%E5%93%AA%E9%87%8C%E6%8A%9B%E5%87%BA%E9%94%99%E8%AF%AF%0A%60%60%60TS%0Atry%20%7B%0A%20%20const%20foo%20%3D%20runTask1()%3B%0A%20%20const%20bar%20%3D%20runTask2()%3B%0A%7D%20catch%20(e)%20%7B%0A%20%20console.log('Error%3A'%2C%20e)%3B%0A%7D%0A%2F%2F%E4%B8%8B%E4%B8%80%E4%B8%AA%E5%BC%80%E5%8F%91%E8%80%85%E5%8F%AF%E8%83%BD%E5%B9%B6%E4%B8%8D%E6%B8%85%E6%A5%9A%E5%93%AA%E4%B8%AA%E5%87%BD%E6%95%B0%E5%8F%AF%E8%83%BD%E4%BC%9A%E6%8A%9B%E5%87%BA%E9%94%99%E8%AF%AF%E3%80%82%E5%9C%A8%E6%B2%A1%E6%9C%89%E9%98%85%E8%AF%BB%20task1%2Ftask2%20%E4%BB%A3%E7%A0%81%E4%BB%A5%E5%8F%8A%E4%BB%96%E4%BB%AC%E5%8F%AF%E8%83%BD%E4%BC%9A%E8%B0%83%E7%94%A8%E7%9A%84%E5%87%BD%E6%95%B0%E6%97%B6%EF%BC%8C%E5%AF%B9%E4%BB%A3%E7%A0%81%20review%20%E7%9A%84%E4%BA%BA%E5%91%98%E5%8F%AF%E8%83%BD%E4%B9%9F%E4%B8%8D%E4%BC%9A%E7%9F%A5%E9%81%93%E9%94%99%E8%AF%AF%E4%BC%9A%E4%BB%8E%E5%93%AA%E9%87%8C%E6%8A%9B%E5%87%BA%E3%80%82%0A%60%60%60%0A%0A%23%23%23%23%23%20%E4%BC%98%E9%9B%85%E7%9A%84%E6%8D%95%E8%8E%B7%E9%94%99%E8%AF%AF%0A%E4%BD%A0%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E4%B8%BA%E6%AF%8F%E4%B8%AA%E5%8F%AF%E8%83%BD%E6%8A%9B%E5%87%BA%E9%94%99%E8%AF%AF%E7%9A%84%E4%BB%A3%E7%A0%81%E6%98%BE%E5%BC%8F%E6%8D%95%E8%8E%B7%EF%BC%8C%E6%9D%A5%E4%BD%BF%E5%85%B6%E4%BC%98%E9%9B%85%EF%BC%9A%0A%60%60%60TS%0Atry%20%7B%0A%20%20const%20foo%20%3D%20runTask1()%3B%0A%7D%20catch%20(e)%20%7B%0A%20%20console.log('Error%3A'%2C%20e)%3B%0A%7D%0A%0Atry%20%7B%0A%20%20const%20bar%20%3D%20runTask2()%3B%0A%7D%20catch%20(e)%20%7B%0A%20%20console.log('Error%3A'%2C%20e)%3B%0A%7D%0A%60%60%60%0A%E4%BD%86%E6%98%AF%E7%8E%B0%E5%9C%A8%EF%BC%8C%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%83%B3%E4%BB%8E%E7%AC%AC%E4%B8%80%E4%B8%AA%E4%BB%BB%E5%8A%A1%E4%B8%AD%E4%BC%A0%E9%80%92%E5%8F%98%E9%87%8F%E5%88%B0%E7%AC%AC%E4%BA%8C%E4%B8%AA%E4%BB%BB%E5%8A%A1%E4%B8%AD%EF%BC%8C%E4%BB%A3%E7%A0%81%E4%BC%9A%E5%8F%98%E7%9A%84%E6%B7%B7%E4%B9%B1%EF%BC%88%E6%B3%A8%E6%84%8F%EF%BC%9Afoo%20%E5%8F%98%E9%87%8F%E9%9C%80%E8%A6%81%E7%94%A8%20let%20%E6%98%BE%E5%BC%8F%E6%B3%A8%E8%A7%A3%E5%AE%83%EF%BC%8C%E5%9B%A0%E4%B8%BA%E5%AE%83%E4%B8%8D%E8%83%BD%E4%BB%8E%20runTask1%20%E4%B8%AD%E8%BF%94%E5%9B%9E%E5%87%BA%E6%9D%A5%EF%BC%89%EF%BC%9A%0A%60%60%60TS%0Alet%20foo%3A%20number%3B%20%2F%2F%20Notice%20%E4%BD%BF%E7%94%A8%20let%20%E5%B9%B6%E4%B8%94%E6%98%BE%E5%BC%8F%E6%B3%A8%E6%98%8E%E7%B1%BB%E5%9E%8B%E6%B3%A8%E8%A7%A3%0A%0Atry%20%7B%0A%20%20foo%20%3D%20runTask1()%3B%0A%7D%20catch%20(e)%20%7B%0A%20%20console.log('Error%3A'%2C%20e)%3B%0A%7D%0A%0Atry%20%7B%0A%20%20const%20bar%20%3D%20runTask2(foo)%3B%0A%7D%20catch%20(e)%20%7B%0A%20%20console.log('Error%3A'%2C%20e)%3B%0A%7D%0A%60%60%60%0A%0A%23%23%23%23%23%20%E6%B2%A1%E6%9C%89%E5%9C%A8%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F%E4%B8%AD%E5%BE%88%E5%A5%BD%E7%9A%84%E8%A1%A8%E7%A4%BA%0A%60%60%60TS%0Afunction%20validate(value%3A%20number)%20%7B%0A%20%20if%20(value%20%3C%200%20%7C%7C%20value%20%3E%20100)%20%7B%0A%20%20%20%20throw%20new%20Error('Invalid%20value')%3B%0A%20%20%7D%0A%7D%0A%60%60%60%0A%E5%9C%A8%E8%BF%99%E7%A7%8D%E6%83%85%E5%A2%83%E4%B8%8B%E4%BD%BF%E7%94%A8%20Error%20%E4%B8%8D%E6%98%AF%E4%B8%80%E4%B8%AA%E5%A5%BD%E7%9A%84%E4%B8%BB%E6%84%8F%E3%80%82%E5%9B%A0%E4%B8%BA%E6%B2%A1%E6%9C%89%E7%94%A8%E6%9D%A5%E9%AA%8C%E8%AF%81%E5%87%BD%E6%95%B0%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%AE%9A%E4%B9%89%EF%BC%88%E5%A6%82%EF%BC%9A(value%3A%20number)%20%3D%3E%20void%EF%BC%89%EF%BC%8C%E5%8F%96%E8%80%8C%E4%BB%A3%E4%B9%8B%E4%B8%80%E4%B8%AA%E6%9B%B4%E5%A5%BD%E7%9A%84%E6%96%B9%E5%BC%8F%E6%98%AF%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E9%AA%8C%E8%AF%81%E6%96%B9%E6%B3%95%EF%BC%9A%0A%60%60%60TS%0Afunction%20validate(%0A%20%20value%3A%20number%0A)%3A%20%7B%0A%20%20error%3F%3A%20string%3B%0A%7D%20%7B%0A%20%20if%20(value%20%3C%200%20%7C%7C%20value%20%3E%20100)%20%7B%0A%20%20%20%20return%20%7B%20error%3A%20'Invalid%20value'%20%7D%3B%0A%20%20%7D%0A%7D%0A%60%60%60%0A%0A%23%23%20%E6%B7%B7%E5%90%88%0ATypeScript%20(%E5%92%8C%20JavaScript)%20%E7%B1%BB%E5%8F%AA%E8%83%BD%E4%B8%A5%E6%A0%BC%E7%9A%84%E5%8D%95%E7%BB%A7%E6%89%BF%EF%BC%8C%E5%9B%A0%E6%AD%A4%E4%BD%A0%E4%B8%8D%E8%83%BD%E5%81%9A%EF%BC%9A%0A%60%60%60TS%0Aclass%20User%20extends%20Tagged%2C%20Timestamped%20%7B%20%2F%2F%20ERROR%20%3A%20%E4%B8%8D%E8%83%BD%E5%A4%9A%E9%87%8D%E7%BB%A7%E6%89%BF%0A%20%20%2F%2F%20..%0A%7D%0A%60%60%60%0A%0A%E9%87%87%E7%94%A8%E5%87%BD%E6%95%B0%20B%20%E6%8E%A5%E5%8F%97%E4%B8%80%E4%B8%AA%E7%B1%BB%20A%EF%BC%8C%E5%B9%B6%E4%B8%94%E8%BF%94%E5%9B%9E%E4%B8%80%E4%B8%AA%E5%B8%A6%E6%9C%89%E6%96%B0%E5%8A%9F%E8%83%BD%E7%9A%84%E7%B1%BB%E7%9A%84%E6%96%B9%E5%BC%8F%E6%9D%A5%E6%9B%BF%E4%BB%A3%20A%20%E7%B1%BB%E6%89%A9%E5%B1%95%20B%20%E6%9D%A5%E8%8E%B7%E5%8F%96%20B%20%E4%B8%8A%E7%9A%84%E5%8A%9F%E8%83%BD%EF%BC%8C%E5%89%8D%E8%80%85%E4%B8%AD%E7%9A%84%20B%20%E5%8D%B3%E6%98%AF%E6%B7%B7%E5%90%88%E3%80%82%0A%0A%E3%80%8C%E6%B7%B7%E5%90%88%E3%80%8D%E6%98%AF%E4%B8%80%E4%B8%AA%E5%87%BD%E6%95%B0%EF%BC%9A%0A%0A1%E3%80%81%E4%BC%A0%E5%85%A5%E4%B8%80%E4%B8%AA%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%EF%BC%9B%0A2%E3%80%81%E5%88%9B%E5%BB%BA%E4%B8%80%E4%B8%AA%E5%B8%A6%E6%9C%89%E6%96%B0%E5%8A%9F%E8%83%BD%EF%BC%8C%E5%B9%B6%E4%B8%94%E6%89%A9%E5%B1%95%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0%E7%9A%84%E6%96%B0%E7%B1%BB%EF%BC%9B%0A3%E3%80%81%E8%BF%94%E5%9B%9E%E8%BF%99%E4%B8%AA%E6%96%B0%E7%B1%BB%E3%80%82%0A%0A%60%60%60ts%20%20%20%0A%2F%2F%20%E6%89%80%E6%9C%89%20mixins%20%E9%83%BD%E9%9C%80%E8%A6%81%0Atype%20Constructor%3CT%20%3D%20%7B%7D%3E%20%3D%20new%20(...args%3A%20any%5B%5D)%20%3D%3E%20T%3B%0A%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0A%2F%2F%20mixins%20%E4%BE%8B%E5%AD%90%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0A%0A%2F%2F%20%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%E7%9A%84%E6%B7%B7%E5%90%88%E4%BE%8B%E5%AD%90%0Afunction%20TimesTamped%3CTBase%20extends%20Constructor%3E(Base%3A%20TBase)%20%7B%0A%20%20return%20class%20extends%20Base%20%7B%0A%20%20%20%20timestamp%20%3D%20Date.now()%3B%0A%20%20%7D%3B%0A%7D%0A%0A%2F%2F%20%E6%B7%BB%E5%8A%A0%E5%B1%9E%E6%80%A7%E5%92%8C%E6%96%B9%E6%B3%95%E7%9A%84%E6%B7%B7%E5%90%88%E4%BE%8B%E5%AD%90%0Afunction%20Activatable%3CTBase%20extends%20Constructor%3E(Base%3A%20TBase)%20%7B%0A%20%20return%20class%20extends%20Base%20%7B%0A%20%20%20%20isActivated%20%3D%20false%3B%0A%0A%20%20%20%20activate()%20%7B%0A%20%20%20%20%20%20this.isActivated%20%3D%20true%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20deactivate()%20%7B%0A%20%20%20%20%20%20this.isActivated%20%3D%20false%3B%0A%20%20%20%20%7D%0A%20%20%7D%3B%0A%7D%0A%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0A%2F%2F%20%E7%BB%84%E5%90%88%E7%B1%BB%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0A%0A%2F%2F%20%E7%AE%80%E5%8D%95%E7%9A%84%E7%B1%BB%0Aclass%20User%20%7B%0A%20%20name%20%3D%20''%3B%0A%7D%0A%0A%2F%2F%20%E6%B7%BB%E5%8A%A0%20TimesTamped%20%E7%9A%84%20User%0Aconst%20TimestampedUser%20%3D%20TimesTamped(User)%3B%0A%0A%2F%2F%20Tina%20TimesTamped%20%E5%92%8C%20Activatable%20%E7%9A%84%E7%B1%BB%0Aconst%20TimestampedActivatableUser%20%3D%20TimesTamped(Activatable(User))%3B%0A%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0A%2F%2F%20%E4%BD%BF%E7%94%A8%E7%BB%84%E5%90%88%E7%B1%BB%0A%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%0A%0Aconst%20timestampedUserExample%20%3D%20new%20TimestampedUser()%3B%0Aconsole.log(timestampedUserExample.timestamp)%3B%0A%0Aconst%20timestampedActivatableUserExample%20%3D%20new%20TimestampedActivatableUser()%3B%0Aconsole.log(timestampedActivatableUserExample.timestamp)%3B%0Aconsole.log(timestampedActivatableUserExample.isActivated)%3B%0A%60%60%60%0A%0A%23%23%20ThisType%0A%E9%80%9A%E8%BF%87%20ThisType%20%E6%88%91%E4%BB%AC%E5%8F%AF%E4%BB%A5%E5%9C%A8%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E4%B8%AD%E9%94%AE%E5%85%A5%20this%EF%BC%8C%E5%B9%B6%E6%8F%90%E4%BE%9B%E9%80%9A%E8%BF%87%E4%B8%8A%E4%B8%8B%E6%96%87%E7%B1%BB%E5%9E%8B%E6%8E%A7%E5%88%B6%20this%20%E7%B1%BB%E5%9E%8B%E7%9A%84%E4%BE%BF%E6%8D%B7%E6%96%B9%E5%BC%8F%E3%80%82%E5%AE%83%E5%8F%AA%E6%9C%89%E5%9C%A8%20--noImplicitThis%20%E7%9A%84%E9%80%89%E9%A1%B9%E4%B8%8B%E6%89%8D%E6%9C%89%E6%95%88%E3%80%82%0A%0A%E7%8E%B0%E5%9C%A8%EF%BC%8C%E5%9C%A8%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E6%96%B9%E6%B3%95%E4%B8%AD%E7%9A%84%20this%20%E7%B1%BB%E5%9E%8B%EF%BC%8C%E5%B0%86%E7%94%B1%E4%BB%A5%E4%B8%8B%E5%86%B3%E5%AE%9A%EF%BC%9A%0A1%E3%80%81%E5%A6%82%E6%9E%9C%E8%BF%99%E4%B8%AA%E6%96%B9%E6%B3%95%E6%98%BE%E7%A4%BA%E6%8C%87%E5%AE%9A%E4%BA%86%20this%20%E5%8F%82%E6%95%B0%EF%BC%8C%E9%82%A3%E4%B9%88%20this%20%E5%85%B7%E6%9C%89%E8%AF%A5%E5%8F%82%E6%95%B0%E7%9A%84%E7%B1%BB%E5%9E%8B%E3%80%82%EF%BC%88%E4%B8%8B%E4%BE%8B%E5%AD%90%E4%B8%AD%20bar%EF%BC%89%0A2%E3%80%81%E5%90%A6%E5%88%99%EF%BC%8C%E5%A6%82%E6%9E%9C%E6%96%B9%E6%B3%95%E7%94%B1%E5%B8%A6%20this%20%E5%8F%82%E6%95%B0%E7%9A%84%E7%AD%BE%E5%90%8D%E8%BF%9B%E8%A1%8C%E4%B8%8A%E4%B8%8B%E6%96%87%E9%94%AE%E5%85%A5%EF%BC%8C%E9%82%A3%E4%B9%88%20this%20%E5%85%B7%E6%9C%89%E8%AF%A5%E5%8F%82%E6%95%B0%E7%9A%84%E7%B1%BB%E5%9E%8B%E3%80%82%EF%BC%88%E4%B8%8B%E4%BE%8B%E5%AD%90%E4%B8%AD%20foo%EF%BC%89%0A3%E3%80%81%E5%90%A6%E5%88%99%EF%BC%8C%E5%A6%82%E6%9E%9C%20--noImplicitThis%20%E9%80%89%E9%A1%B9%E5%B7%B2%E7%BB%8F%E5%90%AF%E7%94%A8%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E4%B8%AD%E5%8C%85%E5%90%AB%E7%94%B1%20ThisType%3CT%3E%20%E9%94%AE%E5%85%A5%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87%E7%B1%BB%E5%9E%8B%EF%BC%8C%E9%82%A3%E4%B9%88%20this%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E4%B8%BA%20T%E3%80%82%0A4%E3%80%81%E5%90%A6%E5%88%99%EF%BC%8C%E5%A6%82%E6%9E%9C%20--noImplicitThis%20%E9%80%89%E9%A1%B9%E5%B7%B2%E7%BB%8F%E5%90%AF%E7%94%A8%EF%BC%8C%E5%B9%B6%E4%B8%94%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E4%B8%AD%E4%B8%8D%E5%8C%85%E5%90%AB%E7%94%B1%20ThisType%3CT%3E%20%E9%94%AE%E5%85%A5%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87%E7%B1%BB%E5%9E%8B%EF%BC%8C%E9%82%A3%E4%B9%88%20this%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E4%B8%BA%E8%AF%A5%E4%B8%8A%E4%B8%8B%E6%96%87%E7%B1%BB%E5%9E%8B%E3%80%82%0A5%E3%80%81%E5%90%A6%E5%88%99%EF%BC%8C%E5%A6%82%E6%9E%9C%20--noImplicitThis%20%E9%80%89%E9%A1%B9%E5%B7%B2%E7%BB%8F%E5%90%AF%E7%94%A8%EF%BC%8Cthis%20%E5%85%B7%E6%9C%89%E8%AF%A5%E5%AF%B9%E8%B1%A1%E5%AD%97%E9%9D%A2%E9%87%8F%E7%9A%84%E7%B1%BB%E5%9E%8B%E3%80%82%0A6%E3%80%81%E5%90%A6%E5%88%99%EF%BC%8Cthis%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E4%B8%BA%20any%E3%80%82%0A%60%60%60ts%0A%2F%2F%20Compile%20with%20--noImplicitThis%0A%0Atype%20Point%20%3D%20%7B%0A%20%20x%3A%20number%3B%0A%20%20y%3A%20number%3B%0A%20%20moveBy(dx%3A%20number%2C%20dy%3A%20number)%3A%20void%3B%0A%7D%3B%0A%0Alet%20p%3A%20Point%20%3D%20%7B%0A%20%20x%3A%2010%2C%0A%20%20y%3A%2020%2C%0A%20%20moveBy(dx%2C%20dy)%20%7B%0A%20%20%20%20this.x%20%2B%3D%20dx%3B%20%2F%2F%20this%20has%20type%20Point%0A%20%20%20%20this.y%20%2B%3D%20dy%3B%20%2F%2F%20this%20has%20type%20Point%0A%20%20%7D%0A%7D%3B%0A%0Alet%20foo%20%3D%20%7B%0A%20%20x%3A%20'hello'%2C%0A%20%20f(n%3A%20number)%20%7B%0A%20%20%20%20this%3B%20%2F%2F%20%7B%20x%3A%20string%2C%20f(n%3A%20number)%3A%20void%20%7D%0A%20%20%7D%0A%7D%3B%0A%0Alet%20bar%20%3D%20%7B%0A%20%20x%3A%20'hello'%2C%0A%20%20f(this%3A%20%7B%20message%3A%20string%20%7D)%20%7B%0A%20%20%20%20this%3B%20%2F%2F%20%7B%20message%3A%20string%20%7D%0A%20%20%7D%0A%7D%3B%0A%0A%2F%2F%E5%87%BD%E6%95%B0%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%B5%8B%E5%80%BC%E7%BB%99%20obj.xxx%20%E6%88%96%E8%80%85%20obj%5Bxxx%5D%20%E7%9A%84%E7%9B%AE%E6%A0%87%E6%97%B6%EF%BC%8C%E5%9C%A8%E5%87%BD%E6%95%B0%E4%B8%AD%20this%20%E7%9A%84%E7%B1%BB%E5%9E%8B%E5%B0%86%E4%BC%9A%E6%98%AF%20obj%EF%BC%9A%0Aobj.f%20%3D%20function(n)%20%7B%0A%20%20return%20this.x%20-%20n%3B%20%2F%2F%20'this'%20has%20same%20type%20as%20'obj'%0A%7D%3B%0A%0Aobj%5B'f'%5D%20%3D%20function(n)%20%7B%0A%20%20return%20this.x%20-%20n%3B%20%2F%2F%20'this'%20has%20same%20type%20as%20'obj'%0A%7D%3B%0A%60%60%60</center></body></html>